From 81dee67e215b23f0c98182eece122b906d35765a Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 3 Mar 2015 16:21:06 +0530 Subject: [PATCH] staging: sm750fb: add sm750 to staging sm750 of Silicon Motion is pci-e display controller device and has features like dual display and 2D acceleration. This patch adds the driver to staging. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/sm750fb/Kconfig | 10 + drivers/staging/sm750fb/Makefile | 4 + drivers/staging/sm750fb/TODO | 15 + drivers/staging/sm750fb/ddk750.h | 24 + drivers/staging/sm750fb/ddk750_chip.c | 639 ++++++ drivers/staging/sm750fb/ddk750_chip.h | 83 + drivers/staging/sm750fb/ddk750_display.c | 318 +++ drivers/staging/sm750fb/ddk750_display.h | 160 ++ drivers/staging/sm750fb/ddk750_dvi.c | 99 + drivers/staging/sm750fb/ddk750_dvi.h | 67 + drivers/staging/sm750fb/ddk750_help.c | 19 + drivers/staging/sm750fb/ddk750_help.h | 29 + drivers/staging/sm750fb/ddk750_hwi2c.c | 271 +++ drivers/staging/sm750fb/ddk750_hwi2c.h | 10 + drivers/staging/sm750fb/ddk750_mode.c | 205 ++ drivers/staging/sm750fb/ddk750_mode.h | 43 + drivers/staging/sm750fb/ddk750_power.c | 239 ++ drivers/staging/sm750fb/ddk750_power.h | 71 + drivers/staging/sm750fb/ddk750_reg.h | 2616 ++++++++++++++++++++++ drivers/staging/sm750fb/ddk750_sii164.c | 425 ++++ drivers/staging/sm750fb/ddk750_sii164.h | 172 ++ drivers/staging/sm750fb/ddk750_swi2c.c | 535 +++++ drivers/staging/sm750fb/ddk750_swi2c.h | 92 + drivers/staging/sm750fb/modedb.h | 221 ++ drivers/staging/sm750fb/readme | 38 + drivers/staging/sm750fb/sm750.c | 1451 ++++++++++++ drivers/staging/sm750fb/sm750.h | 185 ++ drivers/staging/sm750fb/sm750_accel.c | 516 +++++ drivers/staging/sm750fb/sm750_accel.h | 276 +++ drivers/staging/sm750fb/sm750_cursor.c | 254 +++ drivers/staging/sm750fb/sm750_cursor.h | 17 + drivers/staging/sm750fb/sm750_help.h | 111 + drivers/staging/sm750fb/sm750_hw.c | 640 ++++++ drivers/staging/sm750fb/sm750_hw.h | 104 + 36 files changed, 9962 insertions(+) create mode 100644 drivers/staging/sm750fb/Kconfig create mode 100644 drivers/staging/sm750fb/Makefile create mode 100644 drivers/staging/sm750fb/TODO create mode 100644 drivers/staging/sm750fb/ddk750.h create mode 100644 drivers/staging/sm750fb/ddk750_chip.c create mode 100644 drivers/staging/sm750fb/ddk750_chip.h create mode 100644 drivers/staging/sm750fb/ddk750_display.c create mode 100644 drivers/staging/sm750fb/ddk750_display.h create mode 100644 drivers/staging/sm750fb/ddk750_dvi.c create mode 100644 drivers/staging/sm750fb/ddk750_dvi.h create mode 100644 drivers/staging/sm750fb/ddk750_help.c create mode 100644 drivers/staging/sm750fb/ddk750_help.h create mode 100644 drivers/staging/sm750fb/ddk750_hwi2c.c create mode 100644 drivers/staging/sm750fb/ddk750_hwi2c.h create mode 100644 drivers/staging/sm750fb/ddk750_mode.c create mode 100644 drivers/staging/sm750fb/ddk750_mode.h create mode 100644 drivers/staging/sm750fb/ddk750_power.c create mode 100644 drivers/staging/sm750fb/ddk750_power.h create mode 100644 drivers/staging/sm750fb/ddk750_reg.h create mode 100644 drivers/staging/sm750fb/ddk750_sii164.c create mode 100644 drivers/staging/sm750fb/ddk750_sii164.h create mode 100644 drivers/staging/sm750fb/ddk750_swi2c.c create mode 100644 drivers/staging/sm750fb/ddk750_swi2c.h create mode 100644 drivers/staging/sm750fb/modedb.h create mode 100644 drivers/staging/sm750fb/readme create mode 100644 drivers/staging/sm750fb/sm750.c create mode 100644 drivers/staging/sm750fb/sm750.h create mode 100644 drivers/staging/sm750fb/sm750_accel.c create mode 100644 drivers/staging/sm750fb/sm750_accel.h create mode 100644 drivers/staging/sm750fb/sm750_cursor.c create mode 100644 drivers/staging/sm750fb/sm750_cursor.h create mode 100644 drivers/staging/sm750fb/sm750_help.h create mode 100644 drivers/staging/sm750fb/sm750_hw.c create mode 100644 drivers/staging/sm750fb/sm750_hw.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 45baa83be7ce..5da70fddd036 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -58,6 +58,8 @@ source "drivers/staging/iio/Kconfig" source "drivers/staging/sm7xxfb/Kconfig" +source "drivers/staging/sm750fb/Kconfig" + source "drivers/staging/xgifb/Kconfig" source "drivers/staging/emxx_udc/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 29160790841f..0b922ae30356 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_FB_SM7XX) += sm7xxfb/ +obj-$(CONFIG_FB_SM7XX) += sm750fb/ obj-$(CONFIG_FB_XGI) += xgifb/ obj-$(CONFIG_USB_EMXX) += emxx_udc/ obj-$(CONFIG_FT1000) += ft1000/ diff --git a/drivers/staging/sm750fb/Kconfig b/drivers/staging/sm750fb/Kconfig new file mode 100644 index 000000000000..c40d088a4d3b --- /dev/null +++ b/drivers/staging/sm750fb/Kconfig @@ -0,0 +1,10 @@ +config FB_SM750 + tristate "Silicon Motion SM750 framebuffer support" + depends on FB && PCI + help + Frame buffer driver for the Silicon Motion SM750 chip + with 2D accelearion and dual head support. + + This driver is also available as a module. The module will be + called sm750fb. If you want to compile it as a module, say M + here and read . diff --git a/drivers/staging/sm750fb/Makefile b/drivers/staging/sm750fb/Makefile new file mode 100644 index 000000000000..dcce3f487ed5 --- /dev/null +++ b/drivers/staging/sm750fb/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_FB_SM750) += sm750fb.o + +sm750fb-objs := sm750.o sm750_hw.o sm750_accel.o sm750_cursor.o ddk750_chip.o ddk750_power.o ddk750_mode.o +sm750fb-objs += ddk750_display.o ddk750_help.o ddk750_swi2c.o ddk750_sii164.o ddk750_dvi.o ddk750_hwi2c.o diff --git a/drivers/staging/sm750fb/TODO b/drivers/staging/sm750fb/TODO new file mode 100644 index 000000000000..bc1617249395 --- /dev/null +++ b/drivers/staging/sm750fb/TODO @@ -0,0 +1,15 @@ +TODO: +- lots of clechpatch cleanup +- use kernel coding style +- refine the code and remove unused code +- check on hardware effects of removal of USE_HW_I2C and USE_DVICHIP (these two + are supposed to be sample code which is given here if someone wants to + use those functionalities) +- move it to drivers/video/fbdev +- modify the code for drm framework + +Please send any patches to + Greg Kroah-Hartman + Sudip Mukherjee + Teddy Wang + Sudip Mukherjee diff --git a/drivers/staging/sm750fb/ddk750.h b/drivers/staging/sm750fb/ddk750.h new file mode 100644 index 000000000000..2c10a08ed964 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750.h @@ -0,0 +1,24 @@ +#ifndef DDK750_H__ +#define DDK750_H__ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* RegSC.h --- SM718 SDK +* This file contains the definitions for the System Configuration registers. +* +*******************************************************************/ +#include "ddk750_reg.h" +#include "ddk750_mode.h" +#include "ddk750_chip.h" +#include "ddk750_display.h" +#include "ddk750_power.h" +#include "ddk750_help.h" +#ifdef USE_HW_I2C +#include "ddk750_hwi2c.h" +#endif +#include "ddk750_swi2c.h" +#endif diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c new file mode 100644 index 000000000000..b71169ed063c --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_chip.c @@ -0,0 +1,639 @@ +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_chip.h" +#include "ddk750_power.h" +typedef struct _pllcalparam{ + unsigned char power;/* d : 0~ 6*/ + unsigned char pod; + unsigned char od; + unsigned char value;/* value of 2 power d (2^d) */ +} +pllcalparam; + + +logical_chip_type_t getChipType() +{ + unsigned short physicalID; + char physicalRev; + logical_chip_type_t chip; + + physicalID = devId750;//either 0x718 or 0x750 + physicalRev = revId750; + + if (physicalID == 0x718) + { + chip = SM718; + } + else if (physicalID == 0x750) + { + chip = SM750; + /* SM750 and SM750LE are different in their revision ID only. */ + if (physicalRev == SM750LE_REVISION_ID){ + chip = SM750LE; + } + } + else + { + chip = SM_UNKNOWN; + } + + return chip; +} + + +inline unsigned int twoToPowerOfx(unsigned long x) +{ + unsigned long i; + unsigned long result = 1; + + for (i=1; i<=x; i++) + result *= 2; + return result; +} + +inline unsigned int calcPLL(pll_value_t *pPLL) +{ + return (pPLL->inputFreq * pPLL->M / pPLL->N / twoToPowerOfx(pPLL->OD) / twoToPowerOfx(pPLL->POD)); +} + +unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL) +{ + unsigned int ulPllReg = 0; + + pPLL->inputFreq = DEFAULT_INPUT_CLOCK; + pPLL->clockType = clockType; + + switch (clockType) + { + case MXCLK_PLL: + ulPllReg = PEEK32(MXCLK_PLL_CTRL); + break; + case PRIMARY_PLL: + ulPllReg = PEEK32(PANEL_PLL_CTRL); + break; + case SECONDARY_PLL: + ulPllReg = PEEK32(CRT_PLL_CTRL); + break; + case VGA0_PLL: + ulPllReg = PEEK32(VGA_PLL0_CTRL); + break; + case VGA1_PLL: + ulPllReg = PEEK32(VGA_PLL1_CTRL); + break; + } + + pPLL->M = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, M); + pPLL->N = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, N); + pPLL->OD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, OD); + pPLL->POD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, POD); + + return calcPLL(pPLL); +} + + +unsigned int getChipClock() +{ + pll_value_t pll; +#if 1 + if(getChipType() == SM750LE) + return MHz(130); +#endif + + return getPllValue(MXCLK_PLL, &pll); +} + + +/* + * This function set up the main chip clock. + * + * Input: Frequency to be set. + */ +void setChipClock(unsigned int frequency) +{ + pll_value_t pll; + unsigned int ulActualMxClk; +#if 1 + /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */ + if (getChipType() == SM750LE) + return; +#endif + + if (frequency != 0) + { + /* + * Set up PLL, a structure to hold the value to be set in clocks. + */ + pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */ + pll.clockType = MXCLK_PLL; + + /* + * Call calcPllValue() to fill up the other fields for PLL structure. + * Sometime, the chip cannot set up the exact clock required by User. + * Return value from calcPllValue() gives the actual possible clock. + */ + ulActualMxClk = calcPllValue(frequency, &pll); + + /* Master Clock Control: MXCLK_PLL */ + POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll)); + } +} + + + +void setMemoryClock(unsigned int frequency) +{ + unsigned int ulReg, divisor; + #if 1 + /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */ + if (getChipType() == SM750LE) + return; +#endif + if (frequency != 0) + { + /* Set the frequency to the maximum frequency that the DDR Memory can take + which is 336MHz. */ + if (frequency > MHz(336)) + frequency = MHz(336); + + /* Calculate the divisor */ + divisor = (unsigned int) roundedDiv(getChipClock(), frequency); + + /* Set the corresponding divisor in the register. */ + ulReg = PEEK32(CURRENT_GATE); + switch(divisor) + { + default: + case 1: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_1); + break; + case 2: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_2); + break; + case 3: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_3); + break; + case 4: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_4); + break; + } + + setCurrentGate(ulReg); + } +} + + +/* + * This function set up the master clock (MCLK). + * + * Input: Frequency to be set. + * + * NOTE: + * The maximum frequency the engine can run is 168MHz. + */ +void setMasterClock(unsigned int frequency) +{ + unsigned int ulReg, divisor; + #if 1 + /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */ + if (getChipType() == SM750LE) + return; +#endif + if (frequency != 0) + { + /* Set the frequency to the maximum frequency that the SM750 engine can + run, which is about 190 MHz. */ + if (frequency > MHz(190)) + frequency = MHz(190); + + /* Calculate the divisor */ + divisor = (unsigned int) roundedDiv(getChipClock(), frequency); + + /* Set the corresponding divisor in the register. */ + ulReg = PEEK32(CURRENT_GATE); + switch(divisor) + { + default: + case 3: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_3); + break; + case 4: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_4); + break; + case 6: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_6); + break; + case 8: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_8); + break; + } + + setCurrentGate(ulReg); + } +} + + +unsigned int ddk750_getVMSize() +{ + unsigned int reg; + unsigned int data; + + /* sm750le only use 64 mb memory*/ + if(getChipType() == SM750LE) + return MB(64); + + /* for 750,always use power mode0*/ + reg = PEEK32(MODE0_GATE); + reg = FIELD_SET(reg,MODE0_GATE,GPIO,ON); + POKE32(MODE0_GATE,reg); + + /* get frame buffer size from GPIO */ + reg = FIELD_GET(PEEK32(MISC_CTRL),MISC_CTRL,LOCALMEM_SIZE); + switch(reg){ + case MISC_CTRL_LOCALMEM_SIZE_8M: data = MB(8); break; /* 8 Mega byte */ + case MISC_CTRL_LOCALMEM_SIZE_16M: data = MB(16); break; /* 16 Mega byte */ + case MISC_CTRL_LOCALMEM_SIZE_32M: data = MB(32); break; /* 32 Mega byte */ + case MISC_CTRL_LOCALMEM_SIZE_64M: data = MB(64); break; /* 64 Mega byte */ + default: data = 0;break; + } + return data; + +} + +int ddk750_initHw(initchip_param_t * pInitParam) +{ + + unsigned int ulReg; +#if 0 + //move the code to map regiter function. + if(getChipType() == SM718){ + /* turn on big endian bit*/ + ulReg = PEEK32(0x74); + /* now consider register definition in a big endian pattern*/ + POKE32(0x74,ulReg|0x80000000); + } + +#endif + + + if (pInitParam->powerMode != 0 ) + pInitParam->powerMode = 0; + setPowerMode(pInitParam->powerMode); + + /* Enable display power gate & LOCALMEM power gate*/ + ulReg = PEEK32(CURRENT_GATE); + ulReg = FIELD_SET(ulReg, CURRENT_GATE, DISPLAY, ON); + ulReg = FIELD_SET(ulReg,CURRENT_GATE,LOCALMEM,ON); + setCurrentGate(ulReg); + + if(getChipType() != SM750LE){ + /* set panel pll and graphic mode via mmio_88 */ + ulReg = PEEK32(VGA_CONFIGURATION); + ulReg = FIELD_SET(ulReg,VGA_CONFIGURATION,PLL,PANEL); + ulReg = FIELD_SET(ulReg,VGA_CONFIGURATION,MODE,GRAPHIC); + POKE32(VGA_CONFIGURATION,ulReg); + }else{ +#if defined(__i386__) || defined( __x86_64__) + /* set graphic mode via IO method */ + outb_p(0x88,0x3d4); + outb_p(0x06,0x3d5); +#endif + } + + /* Set the Main Chip Clock */ + setChipClock(MHz((unsigned int)pInitParam->chipClock)); + + /* Set up memory clock. */ + setMemoryClock(MHz(pInitParam->memClock)); + + /* Set up master clock */ + setMasterClock(MHz(pInitParam->masterClock)); + + + /* Reset the memory controller. If the memory controller is not reset in SM750, + the system might hang when sw accesses the memory. + The memory should be resetted after changing the MXCLK. + */ + if (pInitParam->resetMemory == 1) + { + ulReg = PEEK32(MISC_CTRL); + ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, RESET); + POKE32(MISC_CTRL, ulReg); + + ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, NORMAL); + POKE32(MISC_CTRL, ulReg); + } + + if (pInitParam->setAllEngOff == 1) + { + enable2DEngine(0); + + /* Disable Overlay, if a former application left it on */ + ulReg = PEEK32(VIDEO_DISPLAY_CTRL); + ulReg = FIELD_SET(ulReg, VIDEO_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(VIDEO_DISPLAY_CTRL, ulReg); + + /* Disable video alpha, if a former application left it on */ + ulReg = PEEK32(VIDEO_ALPHA_DISPLAY_CTRL); + ulReg = FIELD_SET(ulReg, VIDEO_ALPHA_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(VIDEO_ALPHA_DISPLAY_CTRL, ulReg); + + /* Disable alpha plane, if a former application left it on */ + ulReg = PEEK32(ALPHA_DISPLAY_CTRL); + ulReg = FIELD_SET(ulReg, ALPHA_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(ALPHA_DISPLAY_CTRL, ulReg); + +#if 0 + /* Disable LCD hardware cursor, if a former application left it on */ + ulReg = PEEK32(PANEL_HWC_ADDRESS); + ulReg = FIELD_SET(ulReg, PANEL_HWC_ADDRESS, ENABLE, DISABLE); + POKE32(PANEL_HWC_ADDRESS, ulReg); + + /* Disable CRT hardware cursor, if a former application left it on */ + ulReg = PEEK32(CRT_HWC_ADDRESS); + ulReg = FIELD_SET(ulReg, CRT_HWC_ADDRESS, ENABLE, DISABLE); + POKE32(CRT_HWC_ADDRESS, ulReg); + + /* Disable ZV Port 0, if a former application left it on */ + ulReg = PEEK32(ZV0_CAPTURE_CTRL); + ulReg = FIELD_SET(ulReg, ZV0_CAPTURE_CTRL, CAP, DISABLE); + POKE32(ZV0_CAPTURE_CTRL, ulReg); + + /* Disable ZV Port 1, if a former application left it on */ + ulReg = PEEK32(ZV1_CAPTURE_CTRL); + ulReg = FIELD_SET(ulReg, ZV1_CAPTURE_CTRL, CAP, DISABLE); + POKE32(ZV1_CAPTURE_CTRL, ulReg); + + /* Disable ZV Port Power, if a former application left it on */ + enableZVPort(0); + /* Disable DMA Channel, if a former application left it on */ + ulReg = PEEK32(DMA_ABORT_INTERRUPT); + ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT); + POKE32(DMA_ABORT_INTERRUPT, ulReg); + + /* Disable i2c */ + enableI2C(0); +#endif + /* Disable DMA Channel, if a former application left it on */ + ulReg = PEEK32(DMA_ABORT_INTERRUPT); + ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT); + POKE32(DMA_ABORT_INTERRUPT, ulReg); + + /* Disable DMA Power, if a former application left it on */ + enableDMA(0); + } + + /* We can add more initialization as needed. */ + + return 0; +} + +#if 0 + +unsigned int absDiff(unsigned int a, unsigned int b) +{ + if ( a > b ) + return(a - b); + else + return(b - a); +} + +#endif +/* + monk liu @ 4/6/2011: + re-write the calculatePLL function of ddk750. + the original version function does not use some mathematics tricks and shortcut + when it doing the calculation of the best N,M,D combination + I think this version gives a little upgrade in speed + + 750 pll clock formular: + Request Clock = (Input Clock * M )/(N * X) + + Input Clock = 14318181 hz + X = 2 power D + D ={0,1,2,3,4,5,6} + M = {1,...,255} + N = {2,...,15} +*/ +unsigned int calcPllValue(unsigned int request_orig,pll_value_t *pll) +{ + /* used for primary and secondary channel pixel clock pll */ + static pllcalparam xparm_PIXEL[] = { + /* 2^0 = 1*/ {0,0,0,1}, + /* 2^ 1 =2*/ {1,0,1,2}, + /* 2^ 2 = 4*/ {2,0,2,4}, + {3,0,3,8}, + {4,1,3,16}, + {5,2,3,32}, + /* 2^6 = 64 */ {6,3,3,64}, + }; + + /* used for MXCLK (chip clock) */ + static pllcalparam xparm_MXCLK[] = { + /* 2^0 = 1*/ {0,0,0,1}, + /* 2^ 1 =2*/ {1,0,1,2}, + /* 2^ 2 = 4*/ {2,0,2,4}, + {3,0,3,8}, + }; + + /* as sm750 register definition, N located in 2,15 and M located in 1,255 */ + int N,M,X,d; + int xcnt; + int miniDiff; + unsigned int RN,quo,rem,fl_quo; + unsigned int input,request; + unsigned int tmpClock,ret; + pllcalparam * xparm; + +#if 1 + if (getChipType() == SM750LE) + { + /* SM750LE don't have prgrammable PLL and M/N values to work on. + Just return the requested clock. */ + return request_orig; + } +#endif + + ret = 0; + miniDiff = ~0; + request = request_orig / 1000; + input = pll->inputFreq / 1000; + + /* for MXCLK register , no POD provided, so need be treated differently */ + + if(pll->clockType != MXCLK_PLL){ + xparm = &xparm_PIXEL[0]; + xcnt = sizeof(xparm_PIXEL)/sizeof(xparm_PIXEL[0]); + }else{ + xparm = &xparm_MXCLK[0]; + xcnt = sizeof(xparm_MXCLK)/sizeof(xparm_MXCLK[0]); + } + + + for(N = 15;N>1;N--) + { + /* RN will not exceed maximum long if @request <= 285 MHZ (for 32bit cpu) */ + RN = N * request; + quo = RN / input; + rem = RN % input;/* rem always small than 14318181 */ + fl_quo = (rem * 10000 /input); + + for(d = xcnt - 1;d >= 0;d--){ + X = xparm[d].value; + M = quo*X; + M += fl_quo * X / 10000; + /* round step */ + M += (fl_quo*X % 10000)>5000?1:0; + if(M < 256 && M > 0) + { + unsigned int diff; + tmpClock = pll->inputFreq *M / N / X; + diff = absDiff(tmpClock,request_orig); + if(diff < miniDiff) + { + pll->M = M; + pll->N = N; + pll->OD = xparm[d].od; + pll->POD = xparm[d].pod; + miniDiff = diff; + ret = tmpClock; + } + } + } + } + + //printk("Finally: pll->n[%lu],m[%lu],od[%lu],pod[%lu]\n",pll->N,pll->M,pll->OD,pll->POD); + return ret; +} + +unsigned int calcPllValue2( +unsigned int ulRequestClk, /* Required pixel clock in Hz unit */ +pll_value_t *pPLL /* Structure to hold the value to be set in PLL */ +) +{ + unsigned int M, N, OD, POD = 0, diff, pllClk, odPower, podPower; + unsigned int bestDiff = 0xffffffff; /* biggest 32 bit unsigned number */ + unsigned int ret; + /* Init PLL structure to know states */ + pPLL->M = 0; + pPLL->N = 0; + pPLL->OD = 0; + pPLL->POD = 0; + + /* Sanity check: None at the moment */ + + /* Convert everything in Khz range in order to avoid calculation overflow */ + pPLL->inputFreq /= 1000; + ulRequestClk /= 1000; + +#ifndef VALIDATION_CHIP + /* The maximum of post divider is 8. */ + for (POD=0; POD<=3; POD++) +#endif + { + +#ifndef VALIDATION_CHIP + /* MXCLK_PLL does not have post divider. */ + if ((POD > 0) && (pPLL->clockType == MXCLK_PLL)) + break; +#endif + + /* Work out 2 to the power of POD */ + podPower = twoToPowerOfx(POD); + + /* OD has only 2 bits [15:14] and its value must between 0 to 3 */ + for (OD=0; OD<=3; OD++) + { + /* Work out 2 to the power of OD */ + odPower = twoToPowerOfx(OD); + +#ifdef VALIDATION_CHIP + if (odPower > 4) + podPower = 4; + else + podPower = odPower; +#endif + + /* N has 4 bits [11:8] and its value must between 2 and 15. + The N == 1 will behave differently --> Result is not correct. */ + for (N=2; N<=15; N++) + { + /* The formula for PLL is ulRequestClk = inputFreq * M / N / (2^OD) + In the following steps, we try to work out a best M value given the others are known. + To avoid decimal calculation, we use 1000 as multiplier for up to 3 decimal places of accuracy. + */ + M = ulRequestClk * N * odPower * 1000 / pPLL->inputFreq; + M = roundedDiv(M, 1000); + + /* M field has only 8 bits, reject value bigger than 8 bits */ + if (M < 256) + { + /* Calculate the actual clock for a given M & N */ + pllClk = pPLL->inputFreq * M / N / odPower / podPower; + + /* How much are we different from the requirement */ + diff = absDiff(pllClk, ulRequestClk); + + if (diff < bestDiff) + { + bestDiff = diff; + + /* Store M and N values */ + pPLL->M = M; + pPLL->N = N; + pPLL->OD = OD; + +#ifdef VALIDATION_CHIP + if (OD > 2) + POD = 2; + else + POD = OD; +#endif + + pPLL->POD = POD; + } + } + } + } + } + + /* Restore input frequency from Khz to hz unit */ +// pPLL->inputFreq *= 1000; + ulRequestClk *= 1000; + pPLL->inputFreq = DEFAULT_INPUT_CLOCK; /* Default reference clock */ + + /* Output debug information */ + //DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Requested Frequency = %d\n", ulRequestClk)); + //DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Input CLK = %dHz, M=%d, N=%d, OD=%d, POD=%d\n", pPLL->inputFreq, pPLL->M, pPLL->N, pPLL->OD, pPLL->POD)); + + /* Return actual frequency that the PLL can set */ + ret = calcPLL(pPLL); + return ret; +} + + + + + +unsigned int formatPllReg(pll_value_t *pPLL) +{ + unsigned int ulPllReg = 0; + + /* Note that all PLL's have the same format. Here, we just use Panel PLL parameter + to work out the bit fields in the register. + On returning a 32 bit number, the value can be applied to any PLL in the calling function. + */ + ulPllReg = + FIELD_SET( 0, PANEL_PLL_CTRL, BYPASS, OFF) + | FIELD_SET( 0, PANEL_PLL_CTRL, POWER, ON) + | FIELD_SET( 0, PANEL_PLL_CTRL, INPUT, OSC) +#ifndef VALIDATION_CHIP + | FIELD_VALUE(0, PANEL_PLL_CTRL, POD, pPLL->POD) +#endif + | FIELD_VALUE(0, PANEL_PLL_CTRL, OD, pPLL->OD) + | FIELD_VALUE(0, PANEL_PLL_CTRL, N, pPLL->N) + | FIELD_VALUE(0, PANEL_PLL_CTRL, M, pPLL->M); + + return(ulPllReg); +} + + diff --git a/drivers/staging/sm750fb/ddk750_chip.h b/drivers/staging/sm750fb/ddk750_chip.h new file mode 100644 index 000000000000..1c7887512b69 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_chip.h @@ -0,0 +1,83 @@ +#ifndef DDK750_CHIP_H__ +#define DDK750_CHIP_H__ +#define DEFAULT_INPUT_CLOCK 14318181 /* Default reference clock */ +#define SM750LE_REVISION_ID (char)0xfe + +/* This is all the chips recognized by this library */ +typedef enum _logical_chip_type_t +{ + SM_UNKNOWN, + SM718, + SM750, + SM750LE, +} +logical_chip_type_t; + + +typedef enum _clock_type_t +{ + MXCLK_PLL, + PRIMARY_PLL, + SECONDARY_PLL, + VGA0_PLL, + VGA1_PLL, +} +clock_type_t; + +typedef struct _pll_value_t +{ + clock_type_t clockType; + unsigned long inputFreq; /* Input clock frequency to the PLL */ + + /* Use this when clockType = PANEL_PLL */ + unsigned long M; + unsigned long N; + unsigned long OD; + unsigned long POD; +} +pll_value_t; + +/* input struct to initChipParam() function */ +typedef struct _initchip_param_t +{ + unsigned short powerMode; /* Use power mode 0 or 1 */ + unsigned short chipClock; /* Speed of main chip clock in MHz unit + 0 = keep the current clock setting + Others = the new main chip clock + */ + unsigned short memClock; /* Speed of memory clock in MHz unit + 0 = keep the current clock setting + Others = the new memory clock + */ + unsigned short masterClock; /* Speed of master clock in MHz unit + 0 = keep the current clock setting + Others = the new master clock + */ + unsigned short setAllEngOff; /* 0 = leave all engine state untouched. + 1 = make sure they are off: 2D, Overlay, + video alpha, alpha, hardware cursors + */ + unsigned char resetMemory; /* 0 = Do not reset the memory controller + 1 = Reset the memory controller + */ + + /* More initialization parameter can be added if needed */ +} +initchip_param_t; + + +logical_chip_type_t getChipType(void); +unsigned int calcPllValue(unsigned int request,pll_value_t *pll); +unsigned int calcPllValue2(unsigned int,pll_value_t *); +unsigned int formatPllReg(pll_value_t *pPLL); +void ddk750_set_mmio(volatile unsigned char *,unsigned short,char); +unsigned int ddk750_getVMSize(void); +int ddk750_initHw(initchip_param_t *); +unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL); +unsigned int getChipClock(void); +void setChipClock(unsigned int); +void setMemoryClock(unsigned int frequency); +void setMasterClock(unsigned int frequency); + + +#endif diff --git a/drivers/staging/sm750fb/ddk750_display.c b/drivers/staging/sm750fb/ddk750_display.c new file mode 100644 index 000000000000..57192e5b4730 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_display.c @@ -0,0 +1,318 @@ +#include "ddk750_reg.h" +#include "ddk750_help.h" +#include "ddk750_display.h" +#include "ddk750_power.h" +#include "ddk750_dvi.h" + +#define primaryWaitVerticalSync(delay) waitNextVerticalSync(0,delay) + +static void setDisplayControl(int ctrl,int dispState) +{ + /* state != 0 means turn on both timing & plane en_bit */ + unsigned long ulDisplayCtrlReg, ulReservedBits; + int cnt; + + cnt = 0; + + /* Set the primary display control */ + if (!ctrl) + { + ulDisplayCtrlReg = PEEK32(PANEL_DISPLAY_CTRL); + /* Turn on/off the Panel display control */ + if (dispState) + { + /* Timing should be enabled first before enabling the plane + * because changing at the same time does not guarantee that + * the plane will also enabled or disabled. + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + PANEL_DISPLAY_CTRL, TIMING, ENABLE); + POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + PANEL_DISPLAY_CTRL, PLANE, ENABLE); + + /* Added some masks to mask out the reserved bits. + * Sometimes, the reserved bits are set/reset randomly when + * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register + * reserved bits are needed to be masked out. + */ + ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE); + + /* Somehow the register value on the plane is not set + * until a few delay. Need to write + * and read it a couple times + */ + do + { + cnt++; + POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + } while((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != + (ulDisplayCtrlReg & ~ulReservedBits)); + printk("Set Panel Plane enbit:after tried %d times\n",cnt); + } + else + { + /* When turning off, there is no rule on the programming + * sequence since whenever the clock is off, then it does not + * matter whether the plane is enabled or disabled. + * Note: Modifying the plane bit will take effect on the + * next vertical sync. Need to find out if it is necessary to + * wait for 1 vsync before modifying the timing enable bit. + * */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + PANEL_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + PANEL_DISPLAY_CTRL, TIMING, DISABLE); + POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + } + + } + /* Set the secondary display control */ + else + { + ulDisplayCtrlReg = PEEK32(CRT_DISPLAY_CTRL); + + if (dispState) + { + /* Timing should be enabled first before enabling the plane because changing at the + same time does not guarantee that the plane will also enabled or disabled. + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + CRT_DISPLAY_CTRL, TIMING, ENABLE); + POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + CRT_DISPLAY_CTRL, PLANE, ENABLE); + + /* Added some masks to mask out the reserved bits. + * Sometimes, the reserved bits are set/reset randomly when + * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register + * reserved bits are needed to be masked out. + */ + + ulReservedBits = FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | + FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | + FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE) | + FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_4_MASK, ENABLE); + + do + { + cnt++; + POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + } while((PEEK32(CRT_DISPLAY_CTRL) & ~ulReservedBits) != + (ulDisplayCtrlReg & ~ulReservedBits)); + printk("Set Crt Plane enbit:after tried %d times\n",cnt); + } + else + { + /* When turning off, there is no rule on the programming + * sequence since whenever the clock is off, then it does not + * matter whether the plane is enabled or disabled. + * Note: Modifying the plane bit will take effect on the next + * vertical sync. Need to find out if it is necessary to + * wait for 1 vsync before modifying the timing enable bit. + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + CRT_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + CRT_DISPLAY_CTRL, TIMING, DISABLE); + POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + } + } +} + + +static void waitNextVerticalSync(int ctrl,int delay) +{ + unsigned int status; + if(!ctrl){ + /* primary controller */ + + /* Do not wait when the Primary PLL is off or display control is already off. + This will prevent the software to wait forever. */ + if ((FIELD_GET(PEEK32(PANEL_PLL_CTRL), PANEL_PLL_CTRL, POWER) == + PANEL_PLL_CTRL_POWER_OFF) || + (FIELD_GET(PEEK32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, TIMING) == + PANEL_DISPLAY_CTRL_TIMING_DISABLE)) + { + return; + } + + while (delay-- > 0) + { + /* Wait for end of vsync. */ + do + { + status = FIELD_GET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + PANEL_VSYNC); + } + while (status == SYSTEM_CTRL_PANEL_VSYNC_ACTIVE); + + /* Wait for start of vsync. */ + do + { + status = FIELD_GET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + PANEL_VSYNC); + } + while (status == SYSTEM_CTRL_PANEL_VSYNC_INACTIVE); + } + + }else{ + + /* Do not wait when the Primary PLL is off or display control is already off. + This will prevent the software to wait forever. */ + if ((FIELD_GET(PEEK32(CRT_PLL_CTRL), CRT_PLL_CTRL, POWER) == + CRT_PLL_CTRL_POWER_OFF) || + (FIELD_GET(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, TIMING) == + CRT_DISPLAY_CTRL_TIMING_DISABLE)) + { + return; + } + + while (delay-- > 0) + { + /* Wait for end of vsync. */ + do + { + status = FIELD_GET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + CRT_VSYNC); + } + while (status == SYSTEM_CTRL_CRT_VSYNC_ACTIVE); + + /* Wait for start of vsync. */ + do + { + status = FIELD_GET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + CRT_VSYNC); + } + while (status == SYSTEM_CTRL_CRT_VSYNC_INACTIVE); + } + } +} + +static void swPanelPowerSequence_sm750le(int disp,int delay) +{ + unsigned int reg; + reg = PEEK32(DISPLAY_CONTROL_750LE); + if(disp) + reg |= 0xf; + else + reg &= ~0xf; + POKE32(DISPLAY_CONTROL_750LE,reg); +} + +static void swPanelPowerSequence(int disp,int delay) +{ + unsigned int reg; + + /* disp should be 1 to open sequence */ + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,FPEN,disp); + POKE32(PANEL_DISPLAY_CTRL,reg); + primaryWaitVerticalSync(delay); + + + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,DATA,disp); + POKE32(PANEL_DISPLAY_CTRL,reg); + primaryWaitVerticalSync(delay); + + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,VBIASEN,disp); + POKE32(PANEL_DISPLAY_CTRL,reg); + primaryWaitVerticalSync(delay); + + + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,FPEN,disp); + POKE32(PANEL_DISPLAY_CTRL,reg); + primaryWaitVerticalSync(delay); + +} + +void ddk750_setLogicalDispOut(disp_output_t output) +{ + unsigned int reg; + if(output & PNL_2_USAGE){ + /* set panel path controller select */ + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,SELECT,(output & PNL_2_MASK)>>PNL_2_OFFSET); + POKE32(PANEL_DISPLAY_CTRL,reg); + } + + if(output & CRT_2_USAGE){ + /* set crt path controller select */ + reg = PEEK32(CRT_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,CRT_DISPLAY_CTRL,SELECT,(output & CRT_2_MASK)>>CRT_2_OFFSET); + /*se blank off */ + reg = FIELD_SET(reg,CRT_DISPLAY_CTRL,BLANK,OFF); + POKE32(CRT_DISPLAY_CTRL,reg); + + } + + if(output & PRI_TP_USAGE){ + /* set primary timing and plane en_bit */ + setDisplayControl(0,(output&PRI_TP_MASK)>>PRI_TP_OFFSET); + } + + if(output & SEC_TP_USAGE){ + /* set secondary timing and plane en_bit*/ + setDisplayControl(1,(output&SEC_TP_MASK)>>SEC_TP_OFFSET); + } + + if(output & PNL_SEQ_USAGE){ + /* set panel sequence */ + swPanelPowerSequence((output&PNL_SEQ_MASK)>>PNL_SEQ_OFFSET,4); + } + + if(output & DAC_USAGE) + setDAC((output & DAC_MASK)>>DAC_OFFSET); + + if(output & DPMS_USAGE) + ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET); +} + + +int ddk750_initDVIDisp() +{ + /* Initialize DVI. If the dviInit fail and the VendorID or the DeviceID are + not zeroed, then set the failure flag. If it is zeroe, it might mean + that the system is in Dual CRT Monitor configuration. */ + + /* De-skew enabled with default 111b value. + This will fix some artifacts problem in some mode on board 2.2. + Somehow this fix does not affect board 2.1. + */ + if ((dviInit(1, /* Select Rising Edge */ + 1, /* Select 24-bit bus */ + 0, /* Select Single Edge clock */ + 1, /* Enable HSync as is */ + 1, /* Enable VSync as is */ + 1, /* Enable De-skew */ + 7, /* Set the de-skew setting to maximum setup */ + 1, /* Enable continuous Sync */ + 1, /* Enable PLL Filter */ + 4 /* Use the recommended value for PLL Filter value */ + ) != 0) && (dviGetVendorID() != 0x0000) && (dviGetDeviceID() != 0x0000)) + { + return (-1); + } + + /* TODO: Initialize other display component */ + + /* Success */ + return 0; + +} + diff --git a/drivers/staging/sm750fb/ddk750_display.h b/drivers/staging/sm750fb/ddk750_display.h new file mode 100644 index 000000000000..ae0f84c68de5 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_display.h @@ -0,0 +1,160 @@ +#ifndef DDK750_DISPLAY_H__ +#define DDK750_DISPLAY_H__ + +/* panel path select + 80000[29:28] +*/ + +#define PNL_2_OFFSET 0 +#define PNL_2_MASK (3 << PNL_2_OFFSET) +#define PNL_2_USAGE (PNL_2_MASK << 16) +#define PNL_2_PRI ((0 << PNL_2_OFFSET)|PNL_2_USAGE) +#define PNL_2_SEC ((2 << PNL_2_OFFSET)|PNL_2_USAGE) + + +/* primary timing & plane enable bit + 1: 80000[8] & 80000[2] on + 0: both off +*/ +#define PRI_TP_OFFSET 4 +#define PRI_TP_MASK (1 << PRI_TP_OFFSET) +#define PRI_TP_USAGE (PRI_TP_MASK << 16) +#define PRI_TP_ON ((0x1 << PRI_TP_OFFSET)|PRI_TP_USAGE) +#define PRI_TP_OFF ((0x0 << PRI_TP_OFFSET)|PRI_TP_USAGE) + + +/* panel sequency status + 80000[27:24] +*/ +#define PNL_SEQ_OFFSET 6 +#define PNL_SEQ_MASK (1 << PNL_SEQ_OFFSET) +#define PNL_SEQ_USAGE (PNL_SEQ_MASK << 16) +#define PNL_SEQ_ON ((1 << PNL_SEQ_OFFSET)|PNL_SEQ_USAGE) +#define PNL_SEQ_OFF ((0 << PNL_SEQ_OFFSET)|PNL_SEQ_USAGE) + +/* dual digital output + 80000[19] +*/ +#define DUAL_TFT_OFFSET 8 +#define DUAL_TFT_MASK (1 << DUAL_TFT_OFFSET) +#define DUAL_TFT_USAGE (DUAL_TFT_MASK << 16) +#define DUAL_TFT_ON ((1 << DUAL_TFT_OFFSET)|DUAL_TFT_USAGE) +#define DUAL_TFT_OFF ((0 << DUAL_TFT_OFFSET)|DUAL_TFT_USAGE) + +/* secondary timing & plane enable bit + 1:80200[8] & 80200[2] on + 0: both off +*/ +#define SEC_TP_OFFSET 5 +#define SEC_TP_MASK (1<< SEC_TP_OFFSET) +#define SEC_TP_USAGE (SEC_TP_MASK << 16) +#define SEC_TP_ON ((0x1 << SEC_TP_OFFSET)|SEC_TP_USAGE) +#define SEC_TP_OFF ((0x0 << SEC_TP_OFFSET)|SEC_TP_USAGE) + +/* crt path select + 80200[19:18] +*/ +#define CRT_2_OFFSET 2 +#define CRT_2_MASK (3 << CRT_2_OFFSET) +#define CRT_2_USAGE (CRT_2_MASK << 16) +#define CRT_2_PRI ((0x0 << CRT_2_OFFSET)|CRT_2_USAGE) +#define CRT_2_SEC ((0x2 << CRT_2_OFFSET)|CRT_2_USAGE) + + +/* DAC affect both DVI and DSUB + 4[20] +*/ +#define DAC_OFFSET 7 +#define DAC_MASK (1 << DAC_OFFSET) +#define DAC_USAGE (DAC_MASK << 16) +#define DAC_ON ((0x0<< DAC_OFFSET)|DAC_USAGE) +#define DAC_OFF ((0x1 << DAC_OFFSET)|DAC_USAGE) + +/* DPMS only affect D-SUB head + 0[31:30] +*/ +#define DPMS_OFFSET 9 +#define DPMS_MASK (3 << DPMS_OFFSET) +#define DPMS_USAGE (DPMS_MASK << 16) +#define DPMS_OFF ((3 << DPMS_OFFSET)|DPMS_USAGE) +#define DPMS_ON ((0 << DPMS_OFFSET)|DPMS_USAGE) + + + +/* + LCD1 means panel path TFT1 & panel path DVI (so enable DAC) + CRT means crt path DSUB +*/ +#if 0 +typedef enum _disp_output_t +{ + NO_DISPLAY = DPMS_OFF, + + LCD1_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON|DPMS_OFF|DAC_ON, + LCD1_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON|DPMS_OFF|DAC_ON, + + LCD2_PRI = CRT_2_PRI|PRI_TP_ON|DUAL_TFT_ON|DPMS_OFF, + LCD2_SEC = CRT_2_SEC|SEC_TP_ON|DUAL_TFT_ON|DPMS_OFF, + + DSUB_PRI = CRT_2_PRI|PRI_TP_ON|DAC_ON, + DSUB_SEC = CRT_2_SEC|SEC_TP_ON|DAC_ON, + + LCD1_DSUB_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON| + CRT_2_PRI|SEC_TP_OFF|DAC_ON, + + LCD1_DSUB_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON| + CRT_2_SEC|PRI_TP_OFF|DAC_ON, + + /* LCD1 show primary and DSUB show secondary */ + LCD1_DSUB_DUAL = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON| + CRT_2_SEC|SEC_TP_ON|DAC_ON, + + /* LCD1 show secondary and DSUB show primary */ + LCD1_DSUB_DUAL_SWAP = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON| + CRT_2_PRI|PRI_TP_ON|DAC_ON, + + LCD1_LCD2_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON| + CRT_2_PRI|SEC_TP_OFF|DPMS_OFF|DUAL_TFT_ON, + + LCD1_LCD2_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON| + CRT_2_SEC|PRI_TP_OFF|DPMS_OFF|DUAL_TFT_ON, + + LCD1_LCD2_DSUB_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON|DAC_ON| + CRT_2_PRI|SEC_TP_OFF|DPMS_ON|DUAL_TFT_ON, + + LCD1_LCD2_DSUB_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON|DAC_ON| + CRT_2_SEC|PRI_TP_OFF|DPMS_ON|DUAL_TFT_ON, + + +} +disp_output_t; +#else +typedef enum _disp_output_t{ + do_LCD1_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON|DAC_ON, + do_LCD1_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON|DAC_ON, +#if 0 + do_LCD2_PRI = CRT_2_PRI|PRI_TP_ON, + do_LCD2_SEC = CRT_2_SEC|SEC_TP_ON, +#else + do_LCD2_PRI = CRT_2_PRI|PRI_TP_ON|DUAL_TFT_ON, + do_LCD2_SEC = CRT_2_SEC|SEC_TP_ON|DUAL_TFT_ON, +#endif + /* + do_DSUB_PRI = CRT_2_PRI|PRI_TP_ON|DPMS_ON|DAC_ON, + do_DSUB_SEC = CRT_2_SEC|SEC_TP_ON|DPMS_ON|DAC_ON, + */ +#if 0 + do_CRT_PRI = CRT_2_PRI|PRI_TP_ON, + do_CRT_SEC = CRT_2_SEC|SEC_TP_ON, +#else + do_CRT_PRI = CRT_2_PRI|PRI_TP_ON|DPMS_ON|DAC_ON, + do_CRT_SEC = CRT_2_SEC|SEC_TP_ON|DPMS_ON|DAC_ON, +#endif +} +disp_output_t; +#endif + +void ddk750_setLogicalDispOut(disp_output_t); +int ddk750_initDVIDisp(void); + +#endif diff --git a/drivers/staging/sm750fb/ddk750_dvi.c b/drivers/staging/sm750fb/ddk750_dvi.c new file mode 100644 index 000000000000..1c083e7dc710 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_dvi.c @@ -0,0 +1,99 @@ +#define USE_DVICHIP +#ifdef USE_DVICHIP +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_dvi.h" +#include "ddk750_sii164.h" + + +/* This global variable contains all the supported driver and its corresponding + function API. Please set the function pointer to NULL whenever the function + is not supported. */ +static dvi_ctrl_device_t g_dcftSupportedDviController[] = +{ +#ifdef DVI_CTRL_SII164 + { + .pfnInit = sii164InitChip, + .pfnGetVendorId = sii164GetVendorID, + .pfnGetDeviceId = sii164GetDeviceID, +#ifdef SII164_FULL_FUNCTIONS + .pfnResetChip = sii164ResetChip, + .pfnGetChipString = sii164GetChipString, + .pfnSetPower = sii164SetPower, + .pfnEnableHotPlugDetection = sii164EnableHotPlugDetection, + .pfnIsConnected = sii164IsConnected, + .pfnCheckInterrupt = sii164CheckInterrupt, + .pfnClearInterrupt = sii164ClearInterrupt, +#endif + }, +#endif +}; + + +int dviInit( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue + ) +{ + dvi_ctrl_device_t *pCurrentDviCtrl; + pCurrentDviCtrl = g_dcftSupportedDviController; + if(pCurrentDviCtrl->pfnInit != NULL) + { + return pCurrentDviCtrl->pfnInit(edgeSelect, busSelect, dualEdgeClkSelect, hsyncEnable, + vsyncEnable, deskewEnable, deskewSetting, continuousSyncEnable, + pllFilterEnable, pllFilterValue); + } + return -1;//error +} + + +/* + * dviGetVendorID + * This function gets the vendor ID of the DVI controller chip. + * + * Output: + * Vendor ID + */ +unsigned short dviGetVendorID() +{ + dvi_ctrl_device_t *pCurrentDviCtrl; + + //pCurrentDviCtrl = getDviCtrl(); + pCurrentDviCtrl = g_dcftSupportedDviController; + if (pCurrentDviCtrl != (dvi_ctrl_device_t *)0) + return pCurrentDviCtrl->pfnGetVendorId(); + + return 0x0000; +} + + +/* + * dviGetDeviceID + * This function gets the device ID of the DVI controller chip. + * + * Output: + * Device ID + */ +unsigned short dviGetDeviceID() +{ + dvi_ctrl_device_t *pCurrentDviCtrl; + +// pCurrentDviCtrl = getDviCtrl(); + pCurrentDviCtrl = g_dcftSupportedDviController; + if (pCurrentDviCtrl != (dvi_ctrl_device_t *)0) + return pCurrentDviCtrl->pfnGetDeviceId(); + + return 0x0000; +} + +#endif + + diff --git a/drivers/staging/sm750fb/ddk750_dvi.h b/drivers/staging/sm750fb/ddk750_dvi.h new file mode 100644 index 000000000000..50bcec29b2c0 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_dvi.h @@ -0,0 +1,67 @@ +#ifndef DDK750_DVI_H__ +#define DDK750_DVI_H__ + +/* dvi chip stuffs structros */ + +typedef long (*PFN_DVICTRL_INIT)( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue); +typedef void (*PFN_DVICTRL_RESETCHIP)(void); +typedef char* (*PFN_DVICTRL_GETCHIPSTRING)(void); +typedef unsigned short (*PFN_DVICTRL_GETVENDORID)(void); +typedef unsigned short (*PFN_DVICTRL_GETDEVICEID)(void); +typedef void (*PFN_DVICTRL_SETPOWER)(unsigned char powerUp); +typedef void (*PFN_DVICTRL_HOTPLUGDETECTION)(unsigned char enableHotPlug); +typedef unsigned char (*PFN_DVICTRL_ISCONNECTED)(void); +typedef unsigned char (*PFN_DVICTRL_CHECKINTERRUPT)(void); +typedef void (*PFN_DVICTRL_CLEARINTERRUPT)(void); + + + +/* Structure to hold all the function pointer to the DVI Controller. */ +typedef struct _dvi_ctrl_device_t +{ + PFN_DVICTRL_INIT pfnInit; + PFN_DVICTRL_RESETCHIP pfnResetChip; + PFN_DVICTRL_GETCHIPSTRING pfnGetChipString; + PFN_DVICTRL_GETVENDORID pfnGetVendorId; + PFN_DVICTRL_GETDEVICEID pfnGetDeviceId; + PFN_DVICTRL_SETPOWER pfnSetPower; + PFN_DVICTRL_HOTPLUGDETECTION pfnEnableHotPlugDetection; + PFN_DVICTRL_ISCONNECTED pfnIsConnected; + PFN_DVICTRL_CHECKINTERRUPT pfnCheckInterrupt; + PFN_DVICTRL_CLEARINTERRUPT pfnClearInterrupt; +} dvi_ctrl_device_t; +#define DVI_CTRL_SII164 + + + +/* dvi functions prototype */ +int dviInit( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue +); + +unsigned short dviGetVendorID(void); +unsigned short dviGetDeviceID(void); + + + +#endif + diff --git a/drivers/staging/sm750fb/ddk750_help.c b/drivers/staging/sm750fb/ddk750_help.c new file mode 100644 index 000000000000..cc00d2b32436 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_help.c @@ -0,0 +1,19 @@ +//#include "ddk750_reg.h" +//#include "ddk750_chip.h" +#include "ddk750_help.h" + +volatile unsigned char __iomem * mmio750 = NULL; +char revId750 = 0; +unsigned short devId750 = 0; + +/* after driver mapped io registers, use this function first */ +void ddk750_set_mmio(volatile unsigned char * addr,unsigned short devId,char revId) +{ + mmio750 = addr; + devId750 = devId; + revId750 = revId; + if(revId == 0xfe) + printk("found sm750le\n"); +} + + diff --git a/drivers/staging/sm750fb/ddk750_help.h b/drivers/staging/sm750fb/ddk750_help.h new file mode 100644 index 000000000000..4fc93b5d41c7 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_help.h @@ -0,0 +1,29 @@ +#ifndef DDK750_HELP_H__ +#define DDK750_HELP_H__ +#include "ddk750_chip.h" +#ifndef USE_INTERNAL_REGISTER_ACCESS + +#include +#include +#include +#include "sm750_help.h" + + +#if 0 +/* if 718 big endian turned on,be aware that don't use this driver for general use,only for ppc big-endian */ +#warning "big endian on target cpu and enable nature big endian support of 718 capability !" +#define PEEK32(addr) __raw_readl((void __iomem *)(mmio750)+(addr)) +#define POKE32(addr,data) __raw_writel((data),(void __iomem*)(mmio750)+(addr)) +#else /* software control endianess */ +#define PEEK32(addr) readl((addr)+mmio750) +#define POKE32(addr,data) writel((data),(addr)+mmio750) +#endif + +extern volatile unsigned char __iomem * mmio750; +extern char revId750; +extern unsigned short devId750; +#else +/* implement if you want use it*/ +#endif + +#endif diff --git a/drivers/staging/sm750fb/ddk750_hwi2c.c b/drivers/staging/sm750fb/ddk750_hwi2c.c new file mode 100644 index 000000000000..84dfb6f41142 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_hwi2c.c @@ -0,0 +1,271 @@ +#define USE_HW_I2C +#ifdef USE_HW_I2C +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_hwi2c.h" +#include "ddk750_power.h" + +#define MAX_HWI2C_FIFO 16 +#define HWI2C_WAIT_TIMEOUT 0xF0000 + + +int hwI2CInit( + unsigned char busSpeedMode +) +{ + unsigned int value; + + /* Enable GPIO 30 & 31 as IIC clock & data */ + value = PEEK32(GPIO_MUX); + + value = FIELD_SET(value, GPIO_MUX, 30, I2C) | + FIELD_SET(0, GPIO_MUX, 31, I2C); + POKE32(GPIO_MUX, value); + + /* Enable Hardware I2C power. + TODO: Check if we need to enable GPIO power? + */ + enableI2C(1); + + /* Enable the I2C Controller and set the bus speed mode */ + value = PEEK32(I2C_CTRL); + if (busSpeedMode == 0) + value = FIELD_SET(value, I2C_CTRL, MODE, STANDARD); + else + value = FIELD_SET(value, I2C_CTRL, MODE, FAST); + value = FIELD_SET(value, I2C_CTRL, EN, ENABLE); + POKE32(I2C_CTRL, value); + + return 0; +} + + +void hwI2CClose(void) +{ + unsigned int value; + + /* Disable I2C controller */ + value = PEEK32(I2C_CTRL); + value = FIELD_SET(value, I2C_CTRL, EN, DISABLE); + POKE32(I2C_CTRL, value); + + /* Disable I2C Power */ + enableI2C(0); + + /* Set GPIO 30 & 31 back as GPIO pins */ + value = PEEK32(GPIO_MUX); + value = FIELD_SET(value, GPIO_MUX, 30, GPIO); + value = FIELD_SET(value, GPIO_MUX, 31, GPIO); + POKE32(GPIO_MUX, value); +} + + +long hwI2CWaitTXDone(void) +{ + unsigned int timeout; + + /* Wait until the transfer is completed. */ + timeout = HWI2C_WAIT_TIMEOUT; + while ((FIELD_GET(PEEK32(I2C_STATUS), I2C_STATUS, TX) != I2C_STATUS_TX_COMPLETED) && + (timeout != 0)) + timeout--; + + if (timeout == 0) + return (-1); + + return 0; +} + + + +/* + * This function writes data to the i2c slave device registers. + * + * Parameters: + * deviceAddress - i2c Slave device address + * length - Total number of bytes to be written to the device + * pBuffer - The buffer that contains the data to be written to the + * i2c device. + * + * Return Value: + * Total number of bytes those are actually written. + */ +unsigned int hwI2CWriteData( + unsigned char deviceAddress, + unsigned int length, + unsigned char *pBuffer +) +{ + unsigned char count, i; + unsigned int totalBytes = 0; + + /* Set the Device Address */ + POKE32(I2C_SLAVE_ADDRESS, deviceAddress & ~0x01); + + /* Write data. + * Note: + * Only 16 byte can be accessed per i2c start instruction. + */ + do + { + /* Reset I2C by writing 0 to I2C_RESET register to clear the previous status. */ + POKE32(I2C_RESET, 0); + + /* Set the number of bytes to be written */ + if (length < MAX_HWI2C_FIFO) + count = length - 1; + else + count = MAX_HWI2C_FIFO - 1; + POKE32(I2C_BYTE_COUNT, count); + + /* Move the data to the I2C data register */ + for (i = 0; i <= count; i++) + POKE32(I2C_DATA0 + i, *pBuffer++); + + /* Start the I2C */ + POKE32(I2C_CTRL, FIELD_SET(PEEK32(I2C_CTRL), I2C_CTRL, CTRL, START)); + + /* Wait until the transfer is completed. */ + if (hwI2CWaitTXDone() != 0) + break; + + /* Substract length */ + length -= (count + 1); + + /* Total byte written */ + totalBytes += (count + 1); + + } while (length > 0); + + return totalBytes; +} + + + + +/* + * This function reads data from the slave device and stores them + * in the given buffer + * + * Parameters: + * deviceAddress - i2c Slave device address + * length - Total number of bytes to be read + * pBuffer - Pointer to a buffer to be filled with the data read + * from the slave device. It has to be the same size as the + * length to make sure that it can keep all the data read. + * + * Return Value: + * Total number of actual bytes read from the slave device + */ +unsigned int hwI2CReadData( + unsigned char deviceAddress, + unsigned int length, + unsigned char *pBuffer +) +{ + unsigned char count, i; + unsigned int totalBytes = 0; + + /* Set the Device Address */ + POKE32(I2C_SLAVE_ADDRESS, deviceAddress | 0x01); + + /* Read data and save them to the buffer. + * Note: + * Only 16 byte can be accessed per i2c start instruction. + */ + do + { + /* Reset I2C by writing 0 to I2C_RESET register to clear all the status. */ + POKE32(I2C_RESET, 0); + + /* Set the number of bytes to be read */ + if (length <= MAX_HWI2C_FIFO) + count = length - 1; + else + count = MAX_HWI2C_FIFO - 1; + POKE32(I2C_BYTE_COUNT, count); + + /* Start the I2C */ + POKE32(I2C_CTRL, FIELD_SET(PEEK32(I2C_CTRL), I2C_CTRL, CTRL, START)); + + /* Wait until transaction done. */ + if (hwI2CWaitTXDone() != 0) + break; + + /* Save the data to the given buffer */ + for (i = 0; i <= count; i++) + *pBuffer++ = PEEK32(I2C_DATA0 + i); + + /* Substract length by 16 */ + length -= (count + 1); + + /* Number of bytes read. */ + totalBytes += (count + 1); + + } while (length > 0); + + return totalBytes; +} + + + + +/* + * This function reads the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be read from + * registerIndex - Slave device's register to be read + * + * Return Value: + * Register value + */ +unsigned char hwI2CReadReg( + unsigned char deviceAddress, + unsigned char registerIndex +) +{ + unsigned char value = (0xFF); + + if (hwI2CWriteData(deviceAddress, 1, ®isterIndex) == 1) + hwI2CReadData(deviceAddress, 1, &value); + + return value; +} + + + + + +/* + * This function writes a value to the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be written + * registerIndex - Slave device's register to be written + * data - Data to be written to the register + * + * Result: + * 0 - Success + * -1 - Fail + */ +int hwI2CWriteReg( + unsigned char deviceAddress, + unsigned char registerIndex, + unsigned char data +) +{ + unsigned char value[2]; + + value[0] = registerIndex; + value[1] = data; + if (hwI2CWriteData(deviceAddress, 2, value) == 2) + return 0; + + return (-1); +} + + +#endif diff --git a/drivers/staging/sm750fb/ddk750_hwi2c.h b/drivers/staging/sm750fb/ddk750_hwi2c.h new file mode 100644 index 000000000000..ad311493c9fc --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_hwi2c.h @@ -0,0 +1,10 @@ +#ifndef DDK750_HWI2C_H__ +#define DDK750_HWI2C_H__ + +/* hwi2c functions */ +int hwI2CInit(unsigned char busSpeedMode); +void hwI2CClose(void); + +unsigned char hwI2CReadReg(unsigned char deviceAddress,unsigned char registerIndex); +int hwI2CWriteReg(unsigned char deviceAddress,unsigned char registerIndex,unsigned char data); +#endif diff --git a/drivers/staging/sm750fb/ddk750_mode.c b/drivers/staging/sm750fb/ddk750_mode.c new file mode 100644 index 000000000000..2e418fb6ffde --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_mode.c @@ -0,0 +1,205 @@ + +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_mode.h" +#include "ddk750_chip.h" + +/* + SM750LE only: + This function takes care extra registers and bit fields required to set + up a mode in SM750LE + + Explanation about Display Control register: + HW only supports 7 predefined pixel clocks, and clock select is + in bit 29:27 of Display Control register. +*/ +static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, unsigned long dispControl) +{ + unsigned long x, y; + + x = pModeParam->horizontal_display_end; + y = pModeParam->vertical_display_end; + + /* SM750LE has to set up the top-left and bottom-right + registers as well. + Note that normal SM750/SM718 only use those two register for + auto-centering mode. + */ + POKE32(CRT_AUTO_CENTERING_TL, + FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, TOP, 0) + | FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, LEFT, 0)); + + POKE32(CRT_AUTO_CENTERING_BR, + FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, BOTTOM, y-1) + | FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, RIGHT, x-1)); + + /* Assume common fields in dispControl have been properly set before + calling this function. + This function only sets the extra fields in dispControl. + */ + + /* Clear bit 29:27 of display control register */ + dispControl &= FIELD_CLEAR(CRT_DISPLAY_CTRL, CLK); + + /* Set bit 29:27 of display control register for the right clock */ + /* Note that SM750LE only need to supported 7 resoluitons. */ + if ( x == 800 && y == 600 ) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL41); + else if (x == 1024 && y == 768) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL65); + else if (x == 1152 && y == 864) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80); + else if (x == 1280 && y == 768) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80); + else if (x == 1280 && y == 720) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL74); + else if (x == 1280 && y == 960) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108); + else if (x == 1280 && y == 1024) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108); + else /* default to VGA clock */ + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL25); + + /* Set bit 25:24 of display controller */ + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CRTSELECT, CRT); + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, RGBBIT, 24BIT); + + /* Set bit 14 of display controller */ + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLOCK_PHASE, ACTIVE_LOW); + + POKE32(CRT_DISPLAY_CTRL, dispControl); + + return dispControl; +} + + + +/* only timing related registers will be programed */ +static int programModeRegisters(mode_parameter_t * pModeParam,pll_value_t * pll) +{ + int ret = 0; + int cnt = 0; + unsigned int ulTmpValue,ulReg; + if(pll->clockType == SECONDARY_PLL) + { + /* programe secondary pixel clock */ + POKE32(CRT_PLL_CTRL,formatPllReg(pll)); + POKE32(CRT_HORIZONTAL_TOTAL, + FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) + | FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); + + POKE32(CRT_HORIZONTAL_SYNC, + FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) + | FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); + + POKE32(CRT_VERTICAL_TOTAL, + FIELD_VALUE(0, CRT_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) + | FIELD_VALUE(0, CRT_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); + + POKE32(CRT_VERTICAL_SYNC, + FIELD_VALUE(0, CRT_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) + | FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); + + + ulTmpValue = FIELD_VALUE(0,CRT_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)| + FIELD_VALUE(0,CRT_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)| + FIELD_SET(0,CRT_DISPLAY_CTRL,TIMING,ENABLE)| + FIELD_SET(0,CRT_DISPLAY_CTRL,PLANE,ENABLE); + + + if(getChipType() == SM750LE){ + displayControlAdjust_SM750LE(pModeParam,ulTmpValue); + }else{ + ulReg = PEEK32(CRT_DISPLAY_CTRL) + & FIELD_CLEAR(CRT_DISPLAY_CTRL,VSYNC_PHASE) + & FIELD_CLEAR(CRT_DISPLAY_CTRL,HSYNC_PHASE) + & FIELD_CLEAR(CRT_DISPLAY_CTRL,TIMING) + & FIELD_CLEAR(CRT_DISPLAY_CTRL,PLANE); + + POKE32(CRT_DISPLAY_CTRL,ulTmpValue|ulReg); + } + + } + else if(pll->clockType == PRIMARY_PLL) + { + unsigned int ulReservedBits; + POKE32(PANEL_PLL_CTRL,formatPllReg(pll)); + + POKE32(PANEL_HORIZONTAL_TOTAL, + FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) + | FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); + + POKE32(PANEL_HORIZONTAL_SYNC, + FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) + | FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); + + POKE32(PANEL_VERTICAL_TOTAL, + FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) + | FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); + + POKE32(PANEL_VERTICAL_SYNC, + FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) + | FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); + + ulTmpValue = FIELD_VALUE(0,PANEL_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)| + FIELD_VALUE(0,PANEL_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)| + FIELD_VALUE(0,PANEL_DISPLAY_CTRL,CLOCK_PHASE,pModeParam->clock_phase_polarity)| + FIELD_SET(0,PANEL_DISPLAY_CTRL,TIMING,ENABLE)| + FIELD_SET(0,PANEL_DISPLAY_CTRL,PLANE,ENABLE); + + ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE)| + FIELD_SET(0,PANEL_DISPLAY_CTRL,VSYNC,ACTIVE_LOW); + + ulReg = (PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, CLOCK_PHASE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE); + + + /* May a hardware bug or just my test chip (not confirmed). + * PANEL_DISPLAY_CTRL register seems requiring few writes + * before a value can be succesfully written in. + * Added some masks to mask out the reserved bits. + * Note: This problem happens by design. The hardware will wait for the + * next vertical sync to turn on/off the plane. + */ + + POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg); +#if 1 + while((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg)) + { + cnt++; + if(cnt > 1000) + break; + POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg); + } +#endif + } + else{ + ret = -1; + } + return ret; +} + +int ddk750_setModeTiming(mode_parameter_t * parm,clock_type_t clock) +{ + pll_value_t pll; + unsigned int uiActualPixelClk; + pll.inputFreq = DEFAULT_INPUT_CLOCK; + pll.clockType = clock; + + uiActualPixelClk = calcPllValue(parm->pixel_clock,&pll); + if(getChipType() == SM750LE){ + /* set graphic mode via IO method */ + outb_p(0x88,0x3d4); + outb_p(0x06,0x3d5); + } + programModeRegisters(parm,&pll); + return 0; +} + + diff --git a/drivers/staging/sm750fb/ddk750_mode.h b/drivers/staging/sm750fb/ddk750_mode.h new file mode 100644 index 000000000000..6f8df96a8b02 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_mode.h @@ -0,0 +1,43 @@ +#ifndef DDK750_MODE_H__ +#define DDK750_MODE_H__ + +#include "ddk750_chip.h" + +typedef enum _spolarity_t +{ + POS = 0, /* positive */ + NEG, /* negative */ +} +spolarity_t; + + +typedef struct _mode_parameter_t +{ + /* Horizontal timing. */ + unsigned long horizontal_total; + unsigned long horizontal_display_end; + unsigned long horizontal_sync_start; + unsigned long horizontal_sync_width; + spolarity_t horizontal_sync_polarity; + + /* Vertical timing. */ + unsigned long vertical_total; + unsigned long vertical_display_end; + unsigned long vertical_sync_start; + unsigned long vertical_sync_height; + spolarity_t vertical_sync_polarity; + + /* Refresh timing. */ + unsigned long pixel_clock; + unsigned long horizontal_frequency; + unsigned long vertical_frequency; + + /* Clock Phase. This clock phase only applies to Panel. */ + spolarity_t clock_phase_polarity; +} +mode_parameter_t; + +int ddk750_setModeTiming(mode_parameter_t *,clock_type_t); + + +#endif diff --git a/drivers/staging/sm750fb/ddk750_power.c b/drivers/staging/sm750fb/ddk750_power.c new file mode 100644 index 000000000000..98dfcbde1eb6 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_power.c @@ -0,0 +1,239 @@ +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_power.h" + +void ddk750_setDPMS(DPMS_t state) +{ + unsigned int value; + if(getChipType() == SM750LE){ + value = PEEK32(CRT_DISPLAY_CTRL); + POKE32(CRT_DISPLAY_CTRL,FIELD_VALUE(value,CRT_DISPLAY_CTRL,DPMS,state)); + }else{ + value = PEEK32(SYSTEM_CTRL); + value= FIELD_VALUE(value,SYSTEM_CTRL,DPMS,state); + POKE32(SYSTEM_CTRL, value); + } +} + +unsigned int getPowerMode() +{ + if(getChipType() == SM750LE) + return 0; + return (FIELD_GET(PEEK32(POWER_MODE_CTRL), POWER_MODE_CTRL, MODE)); +} + + +/* + * SM50x can operate in one of three modes: 0, 1 or Sleep. + * On hardware reset, power mode 0 is default. + */ +void setPowerMode(unsigned int powerMode) +{ + unsigned int control_value = 0; + + control_value = PEEK32(POWER_MODE_CTRL); + + if(getChipType() == SM750LE) + return; + + switch (powerMode) + { + case POWER_MODE_CTRL_MODE_MODE0: + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, MODE0); + break; + + case POWER_MODE_CTRL_MODE_MODE1: + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, MODE1); + break; + + case POWER_MODE_CTRL_MODE_SLEEP: + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, SLEEP); + break; + + default: + break; + } + + /* Set up other fields in Power Control Register */ + if (powerMode == POWER_MODE_CTRL_MODE_SLEEP) + { + control_value = +#ifdef VALIDATION_CHIP + FIELD_SET( control_value, POWER_MODE_CTRL, 336CLK, OFF) | +#endif + FIELD_SET( control_value, POWER_MODE_CTRL, OSC_INPUT, OFF); + } + else + { + control_value = +#ifdef VALIDATION_CHIP + FIELD_SET( control_value, POWER_MODE_CTRL, 336CLK, ON) | +#endif + FIELD_SET( control_value, POWER_MODE_CTRL, OSC_INPUT, ON); + } + + /* Program new power mode. */ + POKE32(POWER_MODE_CTRL, control_value); +} + +void setCurrentGate(unsigned int gate) +{ + unsigned int gate_reg; + unsigned int mode; + + /* Get current power mode. */ + mode = getPowerMode(); + + switch (mode) + { + case POWER_MODE_CTRL_MODE_MODE0: + gate_reg = MODE0_GATE; + break; + + case POWER_MODE_CTRL_MODE_MODE1: + gate_reg = MODE1_GATE; + break; + + default: + gate_reg = MODE0_GATE; + break; + } + POKE32(gate_reg, gate); +} + + + +/* + * This function enable/disable the 2D engine. + */ +void enable2DEngine(unsigned int enable) +{ + uint32_t gate; + + gate = PEEK32(CURRENT_GATE); + if (enable) + { + gate = FIELD_SET(gate, CURRENT_GATE, DE, ON); + gate = FIELD_SET(gate, CURRENT_GATE, CSC, ON); + } + else + { + gate = FIELD_SET(gate, CURRENT_GATE, DE, OFF); + gate = FIELD_SET(gate, CURRENT_GATE, CSC, OFF); + } + + setCurrentGate(gate); +} + + +/* + * This function enable/disable the ZV Port. + */ +void enableZVPort(unsigned int enable) +{ + uint32_t gate; + + /* Enable ZV Port Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + { + gate = FIELD_SET(gate, CURRENT_GATE, ZVPORT, ON); +#if 1 + /* Using Software I2C */ + gate = FIELD_SET(gate, CURRENT_GATE, GPIO, ON); +#else + /* Using Hardware I2C */ + gate = FIELD_SET(gate, CURRENT_GATE, I2C, ON); +#endif + } + else + { + /* Disable ZV Port Gate. There is no way to know whether the GPIO pins are being used + or not. Therefore, do not disable the GPIO gate. */ + gate = FIELD_SET(gate, CURRENT_GATE, ZVPORT, OFF); + } + + setCurrentGate(gate); +} + + +void enableSSP(unsigned int enable) +{ + uint32_t gate; + + /* Enable SSP Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, SSP, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, SSP, OFF); + + setCurrentGate(gate); +} + +void enableDMA(unsigned int enable) +{ + uint32_t gate; + + /* Enable DMA Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, DMA, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, DMA, OFF); + + setCurrentGate(gate); +} + +/* + * This function enable/disable the GPIO Engine + */ +void enableGPIO(unsigned int enable) +{ + uint32_t gate; + + /* Enable GPIO Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, GPIO, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, GPIO, OFF); + + setCurrentGate(gate); +} + +/* + * This function enable/disable the PWM Engine + */ +void enablePWM(unsigned int enable) +{ + uint32_t gate; + + /* Enable PWM Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, PWM, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, PWM, OFF); + + setCurrentGate(gate); +} + +/* + * This function enable/disable the I2C Engine + */ +void enableI2C(unsigned int enable) +{ + uint32_t gate; + + /* Enable I2C Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, I2C, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, I2C, OFF); + + setCurrentGate(gate); +} + + diff --git a/drivers/staging/sm750fb/ddk750_power.h b/drivers/staging/sm750fb/ddk750_power.h new file mode 100644 index 000000000000..71dc7f980069 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_power.h @@ -0,0 +1,71 @@ +#ifndef DDK750_POWER_H__ +#define DDK750_POWER_H__ + +typedef enum _DPMS_t +{ + crtDPMS_ON = 0x0, + crtDPMS_STANDBY = 0x1, + crtDPMS_SUSPEND = 0x2, + crtDPMS_OFF = 0x3, +} +DPMS_t; + +#define setDAC(off) \ + { \ + POKE32(MISC_CTRL,FIELD_VALUE(PEEK32(MISC_CTRL), \ + MISC_CTRL, \ + DAC_POWER, \ + off)); \ + } + +void ddk750_setDPMS(DPMS_t); + +unsigned int getPowerMode(void); + +/* + * This function sets the current power mode + */ +void setPowerMode(unsigned int powerMode); + +/* + * This function sets current gate + */ +void setCurrentGate(unsigned int gate); + +/* + * This function enable/disable the 2D engine. + */ +void enable2DEngine(unsigned int enable); + +/* + * This function enable/disable the ZV Port + */ +void enableZVPort(unsigned int enable); + +/* + * This function enable/disable the DMA Engine + */ +void enableDMA(unsigned int enable); + +/* + * This function enable/disable the GPIO Engine + */ +void enableGPIO(unsigned int enable); + +/* + * This function enable/disable the PWM Engine + */ +void enablePWM(unsigned int enable); + +/* + * This function enable/disable the I2C Engine + */ +void enableI2C(unsigned int enable); + +/* + * This function enable/disable the SSP. + */ +void enableSSP(unsigned int enable); + + +#endif diff --git a/drivers/staging/sm750fb/ddk750_reg.h b/drivers/staging/sm750fb/ddk750_reg.h new file mode 100644 index 000000000000..2016f97d2a3d --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_reg.h @@ -0,0 +1,2616 @@ +#ifndef DDK750_REG_H__ +#define DDK750_REG_H__ + +/* New register for SM750LE */ +#define DE_STATE1 0x100054 +#define DE_STATE1_DE_ABORT 0:0 +#define DE_STATE1_DE_ABORT_OFF 0 +#define DE_STATE1_DE_ABORT_ON 1 + +#define DE_STATE2 0x100058 +#define DE_STATE2_DE_FIFO 3:3 +#define DE_STATE2_DE_FIFO_NOTEMPTY 0 +#define DE_STATE2_DE_FIFO_EMPTY 1 +#define DE_STATE2_DE_STATUS 2:2 +#define DE_STATE2_DE_STATUS_IDLE 0 +#define DE_STATE2_DE_STATUS_BUSY 1 +#define DE_STATE2_DE_MEM_FIFO 1:1 +#define DE_STATE2_DE_MEM_FIFO_NOTEMPTY 0 +#define DE_STATE2_DE_MEM_FIFO_EMPTY 1 +#define DE_STATE2_DE_RESERVED 0:0 + + + +#define SYSTEM_CTRL 0x000000 +#define SYSTEM_CTRL_DPMS 31:30 +#define SYSTEM_CTRL_DPMS_VPHP 0 +#define SYSTEM_CTRL_DPMS_VPHN 1 +#define SYSTEM_CTRL_DPMS_VNHP 2 +#define SYSTEM_CTRL_DPMS_VNHN 3 +#define SYSTEM_CTRL_PCI_BURST 29:29 +#define SYSTEM_CTRL_PCI_BURST_OFF 0 +#define SYSTEM_CTRL_PCI_BURST_ON 1 +#define SYSTEM_CTRL_PCI_MASTER 25:25 +#define SYSTEM_CTRL_PCI_MASTER_OFF 0 +#define SYSTEM_CTRL_PCI_MASTER_ON 1 +#define SYSTEM_CTRL_LATENCY_TIMER 24:24 +#define SYSTEM_CTRL_LATENCY_TIMER_ON 0 +#define SYSTEM_CTRL_LATENCY_TIMER_OFF 1 +#define SYSTEM_CTRL_DE_FIFO 23:23 +#define SYSTEM_CTRL_DE_FIFO_NOTEMPTY 0 +#define SYSTEM_CTRL_DE_FIFO_EMPTY 1 +#define SYSTEM_CTRL_DE_STATUS 22:22 +#define SYSTEM_CTRL_DE_STATUS_IDLE 0 +#define SYSTEM_CTRL_DE_STATUS_BUSY 1 +#define SYSTEM_CTRL_DE_MEM_FIFO 21:21 +#define SYSTEM_CTRL_DE_MEM_FIFO_NOTEMPTY 0 +#define SYSTEM_CTRL_DE_MEM_FIFO_EMPTY 1 +#define SYSTEM_CTRL_CSC_STATUS 20:20 +#define SYSTEM_CTRL_CSC_STATUS_IDLE 0 +#define SYSTEM_CTRL_CSC_STATUS_BUSY 1 +#define SYSTEM_CTRL_CRT_VSYNC 19:19 +#define SYSTEM_CTRL_CRT_VSYNC_INACTIVE 0 +#define SYSTEM_CTRL_CRT_VSYNC_ACTIVE 1 +#define SYSTEM_CTRL_PANEL_VSYNC 18:18 +#define SYSTEM_CTRL_PANEL_VSYNC_INACTIVE 0 +#define SYSTEM_CTRL_PANEL_VSYNC_ACTIVE 1 +#define SYSTEM_CTRL_CURRENT_BUFFER 17:17 +#define SYSTEM_CTRL_CURRENT_BUFFER_NORMAL 0 +#define SYSTEM_CTRL_CURRENT_BUFFER_FLIP_PENDING 1 +#define SYSTEM_CTRL_DMA_STATUS 16:16 +#define SYSTEM_CTRL_DMA_STATUS_IDLE 0 +#define SYSTEM_CTRL_DMA_STATUS_BUSY 1 +#define SYSTEM_CTRL_PCI_BURST_READ 15:15 +#define SYSTEM_CTRL_PCI_BURST_READ_OFF 0 +#define SYSTEM_CTRL_PCI_BURST_READ_ON 1 +#define SYSTEM_CTRL_DE_ABORT 13:13 +#define SYSTEM_CTRL_DE_ABORT_OFF 0 +#define SYSTEM_CTRL_DE_ABORT_ON 1 +#define SYSTEM_CTRL_PCI_SUBSYS_ID_LOCK 11:11 +#define SYSTEM_CTRL_PCI_SUBSYS_ID_LOCK_OFF 0 +#define SYSTEM_CTRL_PCI_SUBSYS_ID_LOCK_ON 1 +#define SYSTEM_CTRL_PCI_RETRY 7:7 +#define SYSTEM_CTRL_PCI_RETRY_ON 0 +#define SYSTEM_CTRL_PCI_RETRY_OFF 1 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE 5:4 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_1 0 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_2 1 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_4 2 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_8 3 +#define SYSTEM_CTRL_CRT_TRISTATE 3:3 +#define SYSTEM_CTRL_CRT_TRISTATE_OFF 0 +#define SYSTEM_CTRL_CRT_TRISTATE_ON 1 +#define SYSTEM_CTRL_PCIMEM_TRISTATE 2:2 +#define SYSTEM_CTRL_PCIMEM_TRISTATE_OFF 0 +#define SYSTEM_CTRL_PCIMEM_TRISTATE_ON 1 +#define SYSTEM_CTRL_LOCALMEM_TRISTATE 1:1 +#define SYSTEM_CTRL_LOCALMEM_TRISTATE_OFF 0 +#define SYSTEM_CTRL_LOCALMEM_TRISTATE_ON 1 +#define SYSTEM_CTRL_PANEL_TRISTATE 0:0 +#define SYSTEM_CTRL_PANEL_TRISTATE_OFF 0 +#define SYSTEM_CTRL_PANEL_TRISTATE_ON 1 + +#define MISC_CTRL 0x000004 +#define MISC_CTRL_DRAM_RERESH_COUNT 27:27 +#define MISC_CTRL_DRAM_RERESH_COUNT_1ROW 0 +#define MISC_CTRL_DRAM_RERESH_COUNT_3ROW 1 +#define MISC_CTRL_DRAM_REFRESH_TIME 26:25 +#define MISC_CTRL_DRAM_REFRESH_TIME_8 0 +#define MISC_CTRL_DRAM_REFRESH_TIME_16 1 +#define MISC_CTRL_DRAM_REFRESH_TIME_32 2 +#define MISC_CTRL_DRAM_REFRESH_TIME_64 3 +#define MISC_CTRL_INT_OUTPUT 24:24 +#define MISC_CTRL_INT_OUTPUT_NORMAL 0 +#define MISC_CTRL_INT_OUTPUT_INVERT 1 +#define MISC_CTRL_PLL_CLK_COUNT 23:23 +#define MISC_CTRL_PLL_CLK_COUNT_OFF 0 +#define MISC_CTRL_PLL_CLK_COUNT_ON 1 +#define MISC_CTRL_DAC_POWER 20:20 +#define MISC_CTRL_DAC_POWER_ON 0 +#define MISC_CTRL_DAC_POWER_OFF 1 +#define MISC_CTRL_CLK_SELECT 16:16 +#define MISC_CTRL_CLK_SELECT_OSC 0 +#define MISC_CTRL_CLK_SELECT_TESTCLK 1 +#define MISC_CTRL_DRAM_COLUMN_SIZE 15:14 +#define MISC_CTRL_DRAM_COLUMN_SIZE_256 0 +#define MISC_CTRL_DRAM_COLUMN_SIZE_512 1 +#define MISC_CTRL_DRAM_COLUMN_SIZE_1024 2 +#define MISC_CTRL_LOCALMEM_SIZE 13:12 +#define MISC_CTRL_LOCALMEM_SIZE_8M 3 +#define MISC_CTRL_LOCALMEM_SIZE_16M 0 +#define MISC_CTRL_LOCALMEM_SIZE_32M 1 +#define MISC_CTRL_LOCALMEM_SIZE_64M 2 +#define MISC_CTRL_DRAM_TWTR 11:11 +#define MISC_CTRL_DRAM_TWTR_2CLK 0 +#define MISC_CTRL_DRAM_TWTR_1CLK 1 +#define MISC_CTRL_DRAM_TWR 10:10 +#define MISC_CTRL_DRAM_TWR_3CLK 0 +#define MISC_CTRL_DRAM_TWR_2CLK 1 +#define MISC_CTRL_DRAM_TRP 9:9 +#define MISC_CTRL_DRAM_TRP_3CLK 0 +#define MISC_CTRL_DRAM_TRP_4CLK 1 +#define MISC_CTRL_DRAM_TRFC 8:8 +#define MISC_CTRL_DRAM_TRFC_12CLK 0 +#define MISC_CTRL_DRAM_TRFC_14CLK 1 +#define MISC_CTRL_DRAM_TRAS 7:7 +#define MISC_CTRL_DRAM_TRAS_7CLK 0 +#define MISC_CTRL_DRAM_TRAS_8CLK 1 +#define MISC_CTRL_LOCALMEM_RESET 6:6 +#define MISC_CTRL_LOCALMEM_RESET_RESET 0 +#define MISC_CTRL_LOCALMEM_RESET_NORMAL 1 +#define MISC_CTRL_LOCALMEM_STATE 5:5 +#define MISC_CTRL_LOCALMEM_STATE_ACTIVE 0 +#define MISC_CTRL_LOCALMEM_STATE_INACTIVE 1 +#define MISC_CTRL_CPU_CAS_LATENCY 4:4 +#define MISC_CTRL_CPU_CAS_LATENCY_2CLK 0 +#define MISC_CTRL_CPU_CAS_LATENCY_3CLK 1 +#define MISC_CTRL_DLL 3:3 +#define MISC_CTRL_DLL_ON 0 +#define MISC_CTRL_DLL_OFF 1 +#define MISC_CTRL_DRAM_OUTPUT 2:2 +#define MISC_CTRL_DRAM_OUTPUT_LOW 0 +#define MISC_CTRL_DRAM_OUTPUT_HIGH 1 +#define MISC_CTRL_LOCALMEM_BUS_SIZE 1:1 +#define MISC_CTRL_LOCALMEM_BUS_SIZE_32 0 +#define MISC_CTRL_LOCALMEM_BUS_SIZE_64 1 +#define MISC_CTRL_EMBEDDED_LOCALMEM 0:0 +#define MISC_CTRL_EMBEDDED_LOCALMEM_ON 0 +#define MISC_CTRL_EMBEDDED_LOCALMEM_OFF 1 + +#define GPIO_MUX 0x000008 +#define GPIO_MUX_31 31:31 +#define GPIO_MUX_31_GPIO 0 +#define GPIO_MUX_31_I2C 1 +#define GPIO_MUX_30 30:30 +#define GPIO_MUX_30_GPIO 0 +#define GPIO_MUX_30_I2C 1 +#define GPIO_MUX_29 29:29 +#define GPIO_MUX_29_GPIO 0 +#define GPIO_MUX_29_SSP1 1 +#define GPIO_MUX_28 28:28 +#define GPIO_MUX_28_GPIO 0 +#define GPIO_MUX_28_SSP1 1 +#define GPIO_MUX_27 27:27 +#define GPIO_MUX_27_GPIO 0 +#define GPIO_MUX_27_SSP1 1 +#define GPIO_MUX_26 26:26 +#define GPIO_MUX_26_GPIO 0 +#define GPIO_MUX_26_SSP1 1 +#define GPIO_MUX_25 25:25 +#define GPIO_MUX_25_GPIO 0 +#define GPIO_MUX_25_SSP1 1 +#define GPIO_MUX_24 24:24 +#define GPIO_MUX_24_GPIO 0 +#define GPIO_MUX_24_SSP0 1 +#define GPIO_MUX_23 23:23 +#define GPIO_MUX_23_GPIO 0 +#define GPIO_MUX_23_SSP0 1 +#define GPIO_MUX_22 22:22 +#define GPIO_MUX_22_GPIO 0 +#define GPIO_MUX_22_SSP0 1 +#define GPIO_MUX_21 21:21 +#define GPIO_MUX_21_GPIO 0 +#define GPIO_MUX_21_SSP0 1 +#define GPIO_MUX_20 20:20 +#define GPIO_MUX_20_GPIO 0 +#define GPIO_MUX_20_SSP0 1 +#define GPIO_MUX_19 19:19 +#define GPIO_MUX_19_GPIO 0 +#define GPIO_MUX_19_PWM 1 +#define GPIO_MUX_18 18:18 +#define GPIO_MUX_18_GPIO 0 +#define GPIO_MUX_18_PWM 1 +#define GPIO_MUX_17 17:17 +#define GPIO_MUX_17_GPIO 0 +#define GPIO_MUX_17_PWM 1 +#define GPIO_MUX_16 16:16 +#define GPIO_MUX_16_GPIO_ZVPORT 0 +#define GPIO_MUX_16_TEST_DATA 1 +#define GPIO_MUX_15 15:15 +#define GPIO_MUX_15_GPIO_ZVPORT 0 +#define GPIO_MUX_15_TEST_DATA 1 +#define GPIO_MUX_14 14:14 +#define GPIO_MUX_14_GPIO_ZVPORT 0 +#define GPIO_MUX_14_TEST_DATA 1 +#define GPIO_MUX_13 13:13 +#define GPIO_MUX_13_GPIO_ZVPORT 0 +#define GPIO_MUX_13_TEST_DATA 1 +#define GPIO_MUX_12 12:12 +#define GPIO_MUX_12_GPIO_ZVPORT 0 +#define GPIO_MUX_12_TEST_DATA 1 +#define GPIO_MUX_11 11:11 +#define GPIO_MUX_11_GPIO_ZVPORT 0 +#define GPIO_MUX_11_TEST_DATA 1 +#define GPIO_MUX_10 10:10 +#define GPIO_MUX_10_GPIO_ZVPORT 0 +#define GPIO_MUX_10_TEST_DATA 1 +#define GPIO_MUX_9 9:9 +#define GPIO_MUX_9_GPIO_ZVPORT 0 +#define GPIO_MUX_9_TEST_DATA 1 +#define GPIO_MUX_8 8:8 +#define GPIO_MUX_8_GPIO_ZVPORT 0 +#define GPIO_MUX_8_TEST_DATA 1 +#define GPIO_MUX_7 7:7 +#define GPIO_MUX_7_GPIO_ZVPORT 0 +#define GPIO_MUX_7_TEST_DATA 1 +#define GPIO_MUX_6 6:6 +#define GPIO_MUX_6_GPIO_ZVPORT 0 +#define GPIO_MUX_6_TEST_DATA 1 +#define GPIO_MUX_5 5:5 +#define GPIO_MUX_5_GPIO_ZVPORT 0 +#define GPIO_MUX_5_TEST_DATA 1 +#define GPIO_MUX_4 4:4 +#define GPIO_MUX_4_GPIO_ZVPORT 0 +#define GPIO_MUX_4_TEST_DATA 1 +#define GPIO_MUX_3 3:3 +#define GPIO_MUX_3_GPIO_ZVPORT 0 +#define GPIO_MUX_3_TEST_DATA 1 +#define GPIO_MUX_2 2:2 +#define GPIO_MUX_2_GPIO_ZVPORT 0 +#define GPIO_MUX_2_TEST_DATA 1 +#define GPIO_MUX_1 1:1 +#define GPIO_MUX_1_GPIO_ZVPORT 0 +#define GPIO_MUX_1_TEST_DATA 1 +#define GPIO_MUX_0 0:0 +#define GPIO_MUX_0_GPIO_ZVPORT 0 +#define GPIO_MUX_0_TEST_DATA 1 + +#define LOCALMEM_ARBITRATION 0x00000C +#define LOCALMEM_ARBITRATION_ROTATE 28:28 +#define LOCALMEM_ARBITRATION_ROTATE_OFF 0 +#define LOCALMEM_ARBITRATION_ROTATE_ON 1 +#define LOCALMEM_ARBITRATION_VGA 26:24 +#define LOCALMEM_ARBITRATION_VGA_OFF 0 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_DMA 22:20 +#define LOCALMEM_ARBITRATION_DMA_OFF 0 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_ZVPORT1 18:16 +#define LOCALMEM_ARBITRATION_ZVPORT1_OFF 0 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_ZVPORT0 14:12 +#define LOCALMEM_ARBITRATION_ZVPORT0_OFF 0 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_VIDEO 10:8 +#define LOCALMEM_ARBITRATION_VIDEO_OFF 0 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_PANEL 6:4 +#define LOCALMEM_ARBITRATION_PANEL_OFF 0 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_CRT 2:0 +#define LOCALMEM_ARBITRATION_CRT_OFF 0 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_7 7 + +#define PCIMEM_ARBITRATION 0x000010 +#define PCIMEM_ARBITRATION_ROTATE 28:28 +#define PCIMEM_ARBITRATION_ROTATE_OFF 0 +#define PCIMEM_ARBITRATION_ROTATE_ON 1 +#define PCIMEM_ARBITRATION_VGA 26:24 +#define PCIMEM_ARBITRATION_VGA_OFF 0 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_DMA 22:20 +#define PCIMEM_ARBITRATION_DMA_OFF 0 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_ZVPORT1 18:16 +#define PCIMEM_ARBITRATION_ZVPORT1_OFF 0 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_ZVPORT0 14:12 +#define PCIMEM_ARBITRATION_ZVPORT0_OFF 0 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_VIDEO 10:8 +#define PCIMEM_ARBITRATION_VIDEO_OFF 0 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_PANEL 6:4 +#define PCIMEM_ARBITRATION_PANEL_OFF 0 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_CRT 2:0 +#define PCIMEM_ARBITRATION_CRT_OFF 0 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_7 7 + +#define RAW_INT 0x000020 +#define RAW_INT_ZVPORT1_VSYNC 4:4 +#define RAW_INT_ZVPORT1_VSYNC_INACTIVE 0 +#define RAW_INT_ZVPORT1_VSYNC_ACTIVE 1 +#define RAW_INT_ZVPORT1_VSYNC_CLEAR 1 +#define RAW_INT_ZVPORT0_VSYNC 3:3 +#define RAW_INT_ZVPORT0_VSYNC_INACTIVE 0 +#define RAW_INT_ZVPORT0_VSYNC_ACTIVE 1 +#define RAW_INT_ZVPORT0_VSYNC_CLEAR 1 +#define RAW_INT_CRT_VSYNC 2:2 +#define RAW_INT_CRT_VSYNC_INACTIVE 0 +#define RAW_INT_CRT_VSYNC_ACTIVE 1 +#define RAW_INT_CRT_VSYNC_CLEAR 1 +#define RAW_INT_PANEL_VSYNC 1:1 +#define RAW_INT_PANEL_VSYNC_INACTIVE 0 +#define RAW_INT_PANEL_VSYNC_ACTIVE 1 +#define RAW_INT_PANEL_VSYNC_CLEAR 1 +#define RAW_INT_VGA_VSYNC 0:0 +#define RAW_INT_VGA_VSYNC_INACTIVE 0 +#define RAW_INT_VGA_VSYNC_ACTIVE 1 +#define RAW_INT_VGA_VSYNC_CLEAR 1 + +#define INT_STATUS 0x000024 +#define INT_STATUS_GPIO31 31:31 +#define INT_STATUS_GPIO31_INACTIVE 0 +#define INT_STATUS_GPIO31_ACTIVE 1 +#define INT_STATUS_GPIO30 30:30 +#define INT_STATUS_GPIO30_INACTIVE 0 +#define INT_STATUS_GPIO30_ACTIVE 1 +#define INT_STATUS_GPIO29 29:29 +#define INT_STATUS_GPIO29_INACTIVE 0 +#define INT_STATUS_GPIO29_ACTIVE 1 +#define INT_STATUS_GPIO28 28:28 +#define INT_STATUS_GPIO28_INACTIVE 0 +#define INT_STATUS_GPIO28_ACTIVE 1 +#define INT_STATUS_GPIO27 27:27 +#define INT_STATUS_GPIO27_INACTIVE 0 +#define INT_STATUS_GPIO27_ACTIVE 1 +#define INT_STATUS_GPIO26 26:26 +#define INT_STATUS_GPIO26_INACTIVE 0 +#define INT_STATUS_GPIO26_ACTIVE 1 +#define INT_STATUS_GPIO25 25:25 +#define INT_STATUS_GPIO25_INACTIVE 0 +#define INT_STATUS_GPIO25_ACTIVE 1 +#define INT_STATUS_I2C 12:12 +#define INT_STATUS_I2C_INACTIVE 0 +#define INT_STATUS_I2C_ACTIVE 1 +#define INT_STATUS_PWM 11:11 +#define INT_STATUS_PWM_INACTIVE 0 +#define INT_STATUS_PWM_ACTIVE 1 +#define INT_STATUS_DMA1 10:10 +#define INT_STATUS_DMA1_INACTIVE 0 +#define INT_STATUS_DMA1_ACTIVE 1 +#define INT_STATUS_DMA0 9:9 +#define INT_STATUS_DMA0_INACTIVE 0 +#define INT_STATUS_DMA0_ACTIVE 1 +#define INT_STATUS_PCI 8:8 +#define INT_STATUS_PCI_INACTIVE 0 +#define INT_STATUS_PCI_ACTIVE 1 +#define INT_STATUS_SSP1 7:7 +#define INT_STATUS_SSP1_INACTIVE 0 +#define INT_STATUS_SSP1_ACTIVE 1 +#define INT_STATUS_SSP0 6:6 +#define INT_STATUS_SSP0_INACTIVE 0 +#define INT_STATUS_SSP0_ACTIVE 1 +#define INT_STATUS_DE 5:5 +#define INT_STATUS_DE_INACTIVE 0 +#define INT_STATUS_DE_ACTIVE 1 +#define INT_STATUS_ZVPORT1_VSYNC 4:4 +#define INT_STATUS_ZVPORT1_VSYNC_INACTIVE 0 +#define INT_STATUS_ZVPORT1_VSYNC_ACTIVE 1 +#define INT_STATUS_ZVPORT0_VSYNC 3:3 +#define INT_STATUS_ZVPORT0_VSYNC_INACTIVE 0 +#define INT_STATUS_ZVPORT0_VSYNC_ACTIVE 1 +#define INT_STATUS_CRT_VSYNC 2:2 +#define INT_STATUS_CRT_VSYNC_INACTIVE 0 +#define INT_STATUS_CRT_VSYNC_ACTIVE 1 +#define INT_STATUS_PANEL_VSYNC 1:1 +#define INT_STATUS_PANEL_VSYNC_INACTIVE 0 +#define INT_STATUS_PANEL_VSYNC_ACTIVE 1 +#define INT_STATUS_VGA_VSYNC 0:0 +#define INT_STATUS_VGA_VSYNC_INACTIVE 0 +#define INT_STATUS_VGA_VSYNC_ACTIVE 1 + +#define INT_MASK 0x000028 +#define INT_MASK_GPIO31 31:31 +#define INT_MASK_GPIO31_DISABLE 0 +#define INT_MASK_GPIO31_ENABLE 1 +#define INT_MASK_GPIO30 30:30 +#define INT_MASK_GPIO30_DISABLE 0 +#define INT_MASK_GPIO30_ENABLE 1 +#define INT_MASK_GPIO29 29:29 +#define INT_MASK_GPIO29_DISABLE 0 +#define INT_MASK_GPIO29_ENABLE 1 +#define INT_MASK_GPIO28 28:28 +#define INT_MASK_GPIO28_DISABLE 0 +#define INT_MASK_GPIO28_ENABLE 1 +#define INT_MASK_GPIO27 27:27 +#define INT_MASK_GPIO27_DISABLE 0 +#define INT_MASK_GPIO27_ENABLE 1 +#define INT_MASK_GPIO26 26:26 +#define INT_MASK_GPIO26_DISABLE 0 +#define INT_MASK_GPIO26_ENABLE 1 +#define INT_MASK_GPIO25 25:25 +#define INT_MASK_GPIO25_DISABLE 0 +#define INT_MASK_GPIO25_ENABLE 1 +#define INT_MASK_I2C 12:12 +#define INT_MASK_I2C_DISABLE 0 +#define INT_MASK_I2C_ENABLE 1 +#define INT_MASK_PWM 11:11 +#define INT_MASK_PWM_DISABLE 0 +#define INT_MASK_PWM_ENABLE 1 +#define INT_MASK_DMA1 10:10 +#define INT_MASK_DMA1_DISABLE 0 +#define INT_MASK_DMA1_ENABLE 1 +#define INT_MASK_DMA 9:9 +#define INT_MASK_DMA_DISABLE 0 +#define INT_MASK_DMA_ENABLE 1 +#define INT_MASK_PCI 8:8 +#define INT_MASK_PCI_DISABLE 0 +#define INT_MASK_PCI_ENABLE 1 +#define INT_MASK_SSP1 7:7 +#define INT_MASK_SSP1_DISABLE 0 +#define INT_MASK_SSP1_ENABLE 1 +#define INT_MASK_SSP0 6:6 +#define INT_MASK_SSP0_DISABLE 0 +#define INT_MASK_SSP0_ENABLE 1 +#define INT_MASK_DE 5:5 +#define INT_MASK_DE_DISABLE 0 +#define INT_MASK_DE_ENABLE 1 +#define INT_MASK_ZVPORT1_VSYNC 4:4 +#define INT_MASK_ZVPORT1_VSYNC_DISABLE 0 +#define INT_MASK_ZVPORT1_VSYNC_ENABLE 1 +#define INT_MASK_ZVPORT0_VSYNC 3:3 +#define INT_MASK_ZVPORT0_VSYNC_DISABLE 0 +#define INT_MASK_ZVPORT0_VSYNC_ENABLE 1 +#define INT_MASK_CRT_VSYNC 2:2 +#define INT_MASK_CRT_VSYNC_DISABLE 0 +#define INT_MASK_CRT_VSYNC_ENABLE 1 +#define INT_MASK_PANEL_VSYNC 1:1 +#define INT_MASK_PANEL_VSYNC_DISABLE 0 +#define INT_MASK_PANEL_VSYNC_ENABLE 1 +#define INT_MASK_VGA_VSYNC 0:0 +#define INT_MASK_VGA_VSYNC_DISABLE 0 +#define INT_MASK_VGA_VSYNC_ENABLE 1 + +#define CURRENT_GATE 0x000040 +#define CURRENT_GATE_MCLK 15:14 +#ifdef VALIDATION_CHIP + #define CURRENT_GATE_MCLK_112MHZ 0 + #define CURRENT_GATE_MCLK_84MHZ 1 + #define CURRENT_GATE_MCLK_56MHZ 2 + #define CURRENT_GATE_MCLK_42MHZ 3 +#else + #define CURRENT_GATE_MCLK_DIV_3 0 + #define CURRENT_GATE_MCLK_DIV_4 1 + #define CURRENT_GATE_MCLK_DIV_6 2 + #define CURRENT_GATE_MCLK_DIV_8 3 +#endif +#define CURRENT_GATE_M2XCLK 13:12 +#ifdef VALIDATION_CHIP + #define CURRENT_GATE_M2XCLK_336MHZ 0 + #define CURRENT_GATE_M2XCLK_168MHZ 1 + #define CURRENT_GATE_M2XCLK_112MHZ 2 + #define CURRENT_GATE_M2XCLK_84MHZ 3 +#else + #define CURRENT_GATE_M2XCLK_DIV_1 0 + #define CURRENT_GATE_M2XCLK_DIV_2 1 + #define CURRENT_GATE_M2XCLK_DIV_3 2 + #define CURRENT_GATE_M2XCLK_DIV_4 3 +#endif +#define CURRENT_GATE_VGA 10:10 +#define CURRENT_GATE_VGA_OFF 0 +#define CURRENT_GATE_VGA_ON 1 +#define CURRENT_GATE_PWM 9:9 +#define CURRENT_GATE_PWM_OFF 0 +#define CURRENT_GATE_PWM_ON 1 +#define CURRENT_GATE_I2C 8:8 +#define CURRENT_GATE_I2C_OFF 0 +#define CURRENT_GATE_I2C_ON 1 +#define CURRENT_GATE_SSP 7:7 +#define CURRENT_GATE_SSP_OFF 0 +#define CURRENT_GATE_SSP_ON 1 +#define CURRENT_GATE_GPIO 6:6 +#define CURRENT_GATE_GPIO_OFF 0 +#define CURRENT_GATE_GPIO_ON 1 +#define CURRENT_GATE_ZVPORT 5:5 +#define CURRENT_GATE_ZVPORT_OFF 0 +#define CURRENT_GATE_ZVPORT_ON 1 +#define CURRENT_GATE_CSC 4:4 +#define CURRENT_GATE_CSC_OFF 0 +#define CURRENT_GATE_CSC_ON 1 +#define CURRENT_GATE_DE 3:3 +#define CURRENT_GATE_DE_OFF 0 +#define CURRENT_GATE_DE_ON 1 +#define CURRENT_GATE_DISPLAY 2:2 +#define CURRENT_GATE_DISPLAY_OFF 0 +#define CURRENT_GATE_DISPLAY_ON 1 +#define CURRENT_GATE_LOCALMEM 1:1 +#define CURRENT_GATE_LOCALMEM_OFF 0 +#define CURRENT_GATE_LOCALMEM_ON 1 +#define CURRENT_GATE_DMA 0:0 +#define CURRENT_GATE_DMA_OFF 0 +#define CURRENT_GATE_DMA_ON 1 + +#define MODE0_GATE 0x000044 +#define MODE0_GATE_MCLK 15:14 +#define MODE0_GATE_MCLK_112MHZ 0 +#define MODE0_GATE_MCLK_84MHZ 1 +#define MODE0_GATE_MCLK_56MHZ 2 +#define MODE0_GATE_MCLK_42MHZ 3 +#define MODE0_GATE_M2XCLK 13:12 +#define MODE0_GATE_M2XCLK_336MHZ 0 +#define MODE0_GATE_M2XCLK_168MHZ 1 +#define MODE0_GATE_M2XCLK_112MHZ 2 +#define MODE0_GATE_M2XCLK_84MHZ 3 +#define MODE0_GATE_VGA 10:10 +#define MODE0_GATE_VGA_OFF 0 +#define MODE0_GATE_VGA_ON 1 +#define MODE0_GATE_PWM 9:9 +#define MODE0_GATE_PWM_OFF 0 +#define MODE0_GATE_PWM_ON 1 +#define MODE0_GATE_I2C 8:8 +#define MODE0_GATE_I2C_OFF 0 +#define MODE0_GATE_I2C_ON 1 +#define MODE0_GATE_SSP 7:7 +#define MODE0_GATE_SSP_OFF 0 +#define MODE0_GATE_SSP_ON 1 +#define MODE0_GATE_GPIO 6:6 +#define MODE0_GATE_GPIO_OFF 0 +#define MODE0_GATE_GPIO_ON 1 +#define MODE0_GATE_ZVPORT 5:5 +#define MODE0_GATE_ZVPORT_OFF 0 +#define MODE0_GATE_ZVPORT_ON 1 +#define MODE0_GATE_CSC 4:4 +#define MODE0_GATE_CSC_OFF 0 +#define MODE0_GATE_CSC_ON 1 +#define MODE0_GATE_DE 3:3 +#define MODE0_GATE_DE_OFF 0 +#define MODE0_GATE_DE_ON 1 +#define MODE0_GATE_DISPLAY 2:2 +#define MODE0_GATE_DISPLAY_OFF 0 +#define MODE0_GATE_DISPLAY_ON 1 +#define MODE0_GATE_LOCALMEM 1:1 +#define MODE0_GATE_LOCALMEM_OFF 0 +#define MODE0_GATE_LOCALMEM_ON 1 +#define MODE0_GATE_DMA 0:0 +#define MODE0_GATE_DMA_OFF 0 +#define MODE0_GATE_DMA_ON 1 + +#define MODE1_GATE 0x000048 +#define MODE1_GATE_MCLK 15:14 +#define MODE1_GATE_MCLK_112MHZ 0 +#define MODE1_GATE_MCLK_84MHZ 1 +#define MODE1_GATE_MCLK_56MHZ 2 +#define MODE1_GATE_MCLK_42MHZ 3 +#define MODE1_GATE_M2XCLK 13:12 +#define MODE1_GATE_M2XCLK_336MHZ 0 +#define MODE1_GATE_M2XCLK_168MHZ 1 +#define MODE1_GATE_M2XCLK_112MHZ 2 +#define MODE1_GATE_M2XCLK_84MHZ 3 +#define MODE1_GATE_VGA 10:10 +#define MODE1_GATE_VGA_OFF 0 +#define MODE1_GATE_VGA_ON 1 +#define MODE1_GATE_PWM 9:9 +#define MODE1_GATE_PWM_OFF 0 +#define MODE1_GATE_PWM_ON 1 +#define MODE1_GATE_I2C 8:8 +#define MODE1_GATE_I2C_OFF 0 +#define MODE1_GATE_I2C_ON 1 +#define MODE1_GATE_SSP 7:7 +#define MODE1_GATE_SSP_OFF 0 +#define MODE1_GATE_SSP_ON 1 +#define MODE1_GATE_GPIO 6:6 +#define MODE1_GATE_GPIO_OFF 0 +#define MODE1_GATE_GPIO_ON 1 +#define MODE1_GATE_ZVPORT 5:5 +#define MODE1_GATE_ZVPORT_OFF 0 +#define MODE1_GATE_ZVPORT_ON 1 +#define MODE1_GATE_CSC 4:4 +#define MODE1_GATE_CSC_OFF 0 +#define MODE1_GATE_CSC_ON 1 +#define MODE1_GATE_DE 3:3 +#define MODE1_GATE_DE_OFF 0 +#define MODE1_GATE_DE_ON 1 +#define MODE1_GATE_DISPLAY 2:2 +#define MODE1_GATE_DISPLAY_OFF 0 +#define MODE1_GATE_DISPLAY_ON 1 +#define MODE1_GATE_LOCALMEM 1:1 +#define MODE1_GATE_LOCALMEM_OFF 0 +#define MODE1_GATE_LOCALMEM_ON 1 +#define MODE1_GATE_DMA 0:0 +#define MODE1_GATE_DMA_OFF 0 +#define MODE1_GATE_DMA_ON 1 + +#define POWER_MODE_CTRL 0x00004C +#ifdef VALIDATION_CHIP + #define POWER_MODE_CTRL_336CLK 4:4 + #define POWER_MODE_CTRL_336CLK_OFF 0 + #define POWER_MODE_CTRL_336CLK_ON 1 +#endif +#define POWER_MODE_CTRL_OSC_INPUT 3:3 +#define POWER_MODE_CTRL_OSC_INPUT_OFF 0 +#define POWER_MODE_CTRL_OSC_INPUT_ON 1 +#define POWER_MODE_CTRL_ACPI 2:2 +#define POWER_MODE_CTRL_ACPI_OFF 0 +#define POWER_MODE_CTRL_ACPI_ON 1 +#define POWER_MODE_CTRL_MODE 1:0 +#define POWER_MODE_CTRL_MODE_MODE0 0 +#define POWER_MODE_CTRL_MODE_MODE1 1 +#define POWER_MODE_CTRL_MODE_SLEEP 2 + +#define PCI_MASTER_BASE 0x000050 +#define PCI_MASTER_BASE_ADDRESS 7:0 + +#define DEVICE_ID 0x000054 +#define DEVICE_ID_DEVICE_ID 31:16 +#define DEVICE_ID_REVISION_ID 7:0 + +#define PLL_CLK_COUNT 0x000058 +#define PLL_CLK_COUNT_COUNTER 15:0 + +#define PANEL_PLL_CTRL 0x00005C +#define PANEL_PLL_CTRL_BYPASS 18:18 +#define PANEL_PLL_CTRL_BYPASS_OFF 0 +#define PANEL_PLL_CTRL_BYPASS_ON 1 +#define PANEL_PLL_CTRL_POWER 17:17 +#define PANEL_PLL_CTRL_POWER_OFF 0 +#define PANEL_PLL_CTRL_POWER_ON 1 +#define PANEL_PLL_CTRL_INPUT 16:16 +#define PANEL_PLL_CTRL_INPUT_OSC 0 +#define PANEL_PLL_CTRL_INPUT_TESTCLK 1 +#ifdef VALIDATION_CHIP + #define PANEL_PLL_CTRL_OD 15:14 +#else + #define PANEL_PLL_CTRL_POD 15:14 + #define PANEL_PLL_CTRL_OD 13:12 +#endif +#define PANEL_PLL_CTRL_N 11:8 +#define PANEL_PLL_CTRL_M 7:0 + +#define CRT_PLL_CTRL 0x000060 +#define CRT_PLL_CTRL_BYPASS 18:18 +#define CRT_PLL_CTRL_BYPASS_OFF 0 +#define CRT_PLL_CTRL_BYPASS_ON 1 +#define CRT_PLL_CTRL_POWER 17:17 +#define CRT_PLL_CTRL_POWER_OFF 0 +#define CRT_PLL_CTRL_POWER_ON 1 +#define CRT_PLL_CTRL_INPUT 16:16 +#define CRT_PLL_CTRL_INPUT_OSC 0 +#define CRT_PLL_CTRL_INPUT_TESTCLK 1 +#ifdef VALIDATION_CHIP + #define CRT_PLL_CTRL_OD 15:14 +#else + #define CRT_PLL_CTRL_POD 15:14 + #define CRT_PLL_CTRL_OD 13:12 +#endif +#define CRT_PLL_CTRL_N 11:8 +#define CRT_PLL_CTRL_M 7:0 + +#define VGA_PLL0_CTRL 0x000064 +#define VGA_PLL0_CTRL_BYPASS 18:18 +#define VGA_PLL0_CTRL_BYPASS_OFF 0 +#define VGA_PLL0_CTRL_BYPASS_ON 1 +#define VGA_PLL0_CTRL_POWER 17:17 +#define VGA_PLL0_CTRL_POWER_OFF 0 +#define VGA_PLL0_CTRL_POWER_ON 1 +#define VGA_PLL0_CTRL_INPUT 16:16 +#define VGA_PLL0_CTRL_INPUT_OSC 0 +#define VGA_PLL0_CTRL_INPUT_TESTCLK 1 +#ifdef VALIDATION_CHIP + #define VGA_PLL0_CTRL_OD 15:14 +#else + #define VGA_PLL0_CTRL_POD 15:14 + #define VGA_PLL0_CTRL_OD 13:12 +#endif +#define VGA_PLL0_CTRL_N 11:8 +#define VGA_PLL0_CTRL_M 7:0 + +#define VGA_PLL1_CTRL 0x000068 +#define VGA_PLL1_CTRL_BYPASS 18:18 +#define VGA_PLL1_CTRL_BYPASS_OFF 0 +#define VGA_PLL1_CTRL_BYPASS_ON 1 +#define VGA_PLL1_CTRL_POWER 17:17 +#define VGA_PLL1_CTRL_POWER_OFF 0 +#define VGA_PLL1_CTRL_POWER_ON 1 +#define VGA_PLL1_CTRL_INPUT 16:16 +#define VGA_PLL1_CTRL_INPUT_OSC 0 +#define VGA_PLL1_CTRL_INPUT_TESTCLK 1 +#ifdef VALIDATION_CHIP + #define VGA_PLL1_CTRL_OD 15:14 +#else + #define VGA_PLL1_CTRL_POD 15:14 + #define VGA_PLL1_CTRL_OD 13:12 +#endif +#define VGA_PLL1_CTRL_N 11:8 +#define VGA_PLL1_CTRL_M 7:0 + +#define SCRATCH_DATA 0x00006c + +#ifndef VALIDATION_CHIP + +#define MXCLK_PLL_CTRL 0x000070 +#define MXCLK_PLL_CTRL_BYPASS 18:18 +#define MXCLK_PLL_CTRL_BYPASS_OFF 0 +#define MXCLK_PLL_CTRL_BYPASS_ON 1 +#define MXCLK_PLL_CTRL_POWER 17:17 +#define MXCLK_PLL_CTRL_POWER_OFF 0 +#define MXCLK_PLL_CTRL_POWER_ON 1 +#define MXCLK_PLL_CTRL_INPUT 16:16 +#define MXCLK_PLL_CTRL_INPUT_OSC 0 +#define MXCLK_PLL_CTRL_INPUT_TESTCLK 1 +#define MXCLK_PLL_CTRL_POD 15:14 +#define MXCLK_PLL_CTRL_OD 13:12 +#define MXCLK_PLL_CTRL_N 11:8 +#define MXCLK_PLL_CTRL_M 7:0 + +#define VGA_CONFIGURATION 0x000088 +#define VGA_CONFIGURATION_USER_DEFINE 5:4 +#define VGA_CONFIGURATION_PLL 2:2 +#define VGA_CONFIGURATION_PLL_VGA 0 +#define VGA_CONFIGURATION_PLL_PANEL 1 +#define VGA_CONFIGURATION_MODE 1:1 +#define VGA_CONFIGURATION_MODE_TEXT 0 +#define VGA_CONFIGURATION_MODE_GRAPHIC 1 + +#endif + +#define GPIO_DATA 0x010000 +#define GPIO_DATA_31 31:31 +#define GPIO_DATA_30 30:30 +#define GPIO_DATA_29 29:29 +#define GPIO_DATA_28 28:28 +#define GPIO_DATA_27 27:27 +#define GPIO_DATA_26 26:26 +#define GPIO_DATA_25 25:25 +#define GPIO_DATA_24 24:24 +#define GPIO_DATA_23 23:23 +#define GPIO_DATA_22 22:22 +#define GPIO_DATA_21 21:21 +#define GPIO_DATA_20 20:20 +#define GPIO_DATA_19 19:19 +#define GPIO_DATA_18 18:18 +#define GPIO_DATA_17 17:17 +#define GPIO_DATA_16 16:16 +#define GPIO_DATA_15 15:15 +#define GPIO_DATA_14 14:14 +#define GPIO_DATA_13 13:13 +#define GPIO_DATA_12 12:12 +#define GPIO_DATA_11 11:11 +#define GPIO_DATA_10 10:10 +#define GPIO_DATA_9 9:9 +#define GPIO_DATA_8 8:8 +#define GPIO_DATA_7 7:7 +#define GPIO_DATA_6 6:6 +#define GPIO_DATA_5 5:5 +#define GPIO_DATA_4 4:4 +#define GPIO_DATA_3 3:3 +#define GPIO_DATA_2 2:2 +#define GPIO_DATA_1 1:1 +#define GPIO_DATA_0 0:0 + +#define GPIO_DATA_DIRECTION 0x010004 +#define GPIO_DATA_DIRECTION_31 31:31 +#define GPIO_DATA_DIRECTION_31_INPUT 0 +#define GPIO_DATA_DIRECTION_31_OUTPUT 1 +#define GPIO_DATA_DIRECTION_30 30:30 +#define GPIO_DATA_DIRECTION_30_INPUT 0 +#define GPIO_DATA_DIRECTION_30_OUTPUT 1 +#define GPIO_DATA_DIRECTION_29 29:29 +#define GPIO_DATA_DIRECTION_29_INPUT 0 +#define GPIO_DATA_DIRECTION_29_OUTPUT 1 +#define GPIO_DATA_DIRECTION_28 28:28 +#define GPIO_DATA_DIRECTION_28_INPUT 0 +#define GPIO_DATA_DIRECTION_28_OUTPUT 1 +#define GPIO_DATA_DIRECTION_27 27:27 +#define GPIO_DATA_DIRECTION_27_INPUT 0 +#define GPIO_DATA_DIRECTION_27_OUTPUT 1 +#define GPIO_DATA_DIRECTION_26 26:26 +#define GPIO_DATA_DIRECTION_26_INPUT 0 +#define GPIO_DATA_DIRECTION_26_OUTPUT 1 +#define GPIO_DATA_DIRECTION_25 25:25 +#define GPIO_DATA_DIRECTION_25_INPUT 0 +#define GPIO_DATA_DIRECTION_25_OUTPUT 1 +#define GPIO_DATA_DIRECTION_24 24:24 +#define GPIO_DATA_DIRECTION_24_INPUT 0 +#define GPIO_DATA_DIRECTION_24_OUTPUT 1 +#define GPIO_DATA_DIRECTION_23 23:23 +#define GPIO_DATA_DIRECTION_23_INPUT 0 +#define GPIO_DATA_DIRECTION_23_OUTPUT 1 +#define GPIO_DATA_DIRECTION_22 22:22 +#define GPIO_DATA_DIRECTION_22_INPUT 0 +#define GPIO_DATA_DIRECTION_22_OUTPUT 1 +#define GPIO_DATA_DIRECTION_21 21:21 +#define GPIO_DATA_DIRECTION_21_INPUT 0 +#define GPIO_DATA_DIRECTION_21_OUTPUT 1 +#define GPIO_DATA_DIRECTION_20 20:20 +#define GPIO_DATA_DIRECTION_20_INPUT 0 +#define GPIO_DATA_DIRECTION_20_OUTPUT 1 +#define GPIO_DATA_DIRECTION_19 19:19 +#define GPIO_DATA_DIRECTION_19_INPUT 0 +#define GPIO_DATA_DIRECTION_19_OUTPUT 1 +#define GPIO_DATA_DIRECTION_18 18:18 +#define GPIO_DATA_DIRECTION_18_INPUT 0 +#define GPIO_DATA_DIRECTION_18_OUTPUT 1 +#define GPIO_DATA_DIRECTION_17 17:17 +#define GPIO_DATA_DIRECTION_17_INPUT 0 +#define GPIO_DATA_DIRECTION_17_OUTPUT 1 +#define GPIO_DATA_DIRECTION_16 16:16 +#define GPIO_DATA_DIRECTION_16_INPUT 0 +#define GPIO_DATA_DIRECTION_16_OUTPUT 1 +#define GPIO_DATA_DIRECTION_15 15:15 +#define GPIO_DATA_DIRECTION_15_INPUT 0 +#define GPIO_DATA_DIRECTION_15_OUTPUT 1 +#define GPIO_DATA_DIRECTION_14 14:14 +#define GPIO_DATA_DIRECTION_14_INPUT 0 +#define GPIO_DATA_DIRECTION_14_OUTPUT 1 +#define GPIO_DATA_DIRECTION_13 13:13 +#define GPIO_DATA_DIRECTION_13_INPUT 0 +#define GPIO_DATA_DIRECTION_13_OUTPUT 1 +#define GPIO_DATA_DIRECTION_12 12:12 +#define GPIO_DATA_DIRECTION_12_INPUT 0 +#define GPIO_DATA_DIRECTION_12_OUTPUT 1 +#define GPIO_DATA_DIRECTION_11 11:11 +#define GPIO_DATA_DIRECTION_11_INPUT 0 +#define GPIO_DATA_DIRECTION_11_OUTPUT 1 +#define GPIO_DATA_DIRECTION_10 10:10 +#define GPIO_DATA_DIRECTION_10_INPUT 0 +#define GPIO_DATA_DIRECTION_10_OUTPUT 1 +#define GPIO_DATA_DIRECTION_9 9:9 +#define GPIO_DATA_DIRECTION_9_INPUT 0 +#define GPIO_DATA_DIRECTION_9_OUTPUT 1 +#define GPIO_DATA_DIRECTION_8 8:8 +#define GPIO_DATA_DIRECTION_8_INPUT 0 +#define GPIO_DATA_DIRECTION_8_OUTPUT 1 +#define GPIO_DATA_DIRECTION_7 7:7 +#define GPIO_DATA_DIRECTION_7_INPUT 0 +#define GPIO_DATA_DIRECTION_7_OUTPUT 1 +#define GPIO_DATA_DIRECTION_6 6:6 +#define GPIO_DATA_DIRECTION_6_INPUT 0 +#define GPIO_DATA_DIRECTION_6_OUTPUT 1 +#define GPIO_DATA_DIRECTION_5 5:5 +#define GPIO_DATA_DIRECTION_5_INPUT 0 +#define GPIO_DATA_DIRECTION_5_OUTPUT 1 +#define GPIO_DATA_DIRECTION_4 4:4 +#define GPIO_DATA_DIRECTION_4_INPUT 0 +#define GPIO_DATA_DIRECTION_4_OUTPUT 1 +#define GPIO_DATA_DIRECTION_3 3:3 +#define GPIO_DATA_DIRECTION_3_INPUT 0 +#define GPIO_DATA_DIRECTION_3_OUTPUT 1 +#define GPIO_DATA_DIRECTION_2 2:2 +#define GPIO_DATA_DIRECTION_2_INPUT 0 +#define GPIO_DATA_DIRECTION_2_OUTPUT 1 +#define GPIO_DATA_DIRECTION_1 131 +#define GPIO_DATA_DIRECTION_1_INPUT 0 +#define GPIO_DATA_DIRECTION_1_OUTPUT 1 +#define GPIO_DATA_DIRECTION_0 0:0 +#define GPIO_DATA_DIRECTION_0_INPUT 0 +#define GPIO_DATA_DIRECTION_0_OUTPUT 1 + +#define GPIO_INTERRUPT_SETUP 0x010008 +#define GPIO_INTERRUPT_SETUP_TRIGGER_31 22:22 +#define GPIO_INTERRUPT_SETUP_TRIGGER_31_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_31_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_30 21:21 +#define GPIO_INTERRUPT_SETUP_TRIGGER_30_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_30_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_29 20:20 +#define GPIO_INTERRUPT_SETUP_TRIGGER_29_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_29_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_28 19:19 +#define GPIO_INTERRUPT_SETUP_TRIGGER_28_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_28_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_27 18:18 +#define GPIO_INTERRUPT_SETUP_TRIGGER_27_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_27_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_26 17:17 +#define GPIO_INTERRUPT_SETUP_TRIGGER_26_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_26_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_25 16:16 +#define GPIO_INTERRUPT_SETUP_TRIGGER_25_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_25_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_31 14:14 +#define GPIO_INTERRUPT_SETUP_ACTIVE_31_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_31_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_30 13:13 +#define GPIO_INTERRUPT_SETUP_ACTIVE_30_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_30_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_29 12:12 +#define GPIO_INTERRUPT_SETUP_ACTIVE_29_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_29_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_28 11:11 +#define GPIO_INTERRUPT_SETUP_ACTIVE_28_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_28_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_27 10:10 +#define GPIO_INTERRUPT_SETUP_ACTIVE_27_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_27_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_26 9:9 +#define GPIO_INTERRUPT_SETUP_ACTIVE_26_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_26_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_25 8:8 +#define GPIO_INTERRUPT_SETUP_ACTIVE_25_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_25_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_31 6:6 +#define GPIO_INTERRUPT_SETUP_ENABLE_31_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_31_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_30 5:5 +#define GPIO_INTERRUPT_SETUP_ENABLE_30_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_30_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_29 4:4 +#define GPIO_INTERRUPT_SETUP_ENABLE_29_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_29_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_28 3:3 +#define GPIO_INTERRUPT_SETUP_ENABLE_28_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_28_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_27 2:2 +#define GPIO_INTERRUPT_SETUP_ENABLE_27_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_27_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_26 1:1 +#define GPIO_INTERRUPT_SETUP_ENABLE_26_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_26_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_25 0:0 +#define GPIO_INTERRUPT_SETUP_ENABLE_25_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_25_INTERRUPT 1 + +#define GPIO_INTERRUPT_STATUS 0x01000C +#define GPIO_INTERRUPT_STATUS_31 22:22 +#define GPIO_INTERRUPT_STATUS_31_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_31_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_31_RESET 1 +#define GPIO_INTERRUPT_STATUS_30 21:21 +#define GPIO_INTERRUPT_STATUS_30_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_30_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_30_RESET 1 +#define GPIO_INTERRUPT_STATUS_29 20:20 +#define GPIO_INTERRUPT_STATUS_29_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_29_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_29_RESET 1 +#define GPIO_INTERRUPT_STATUS_28 19:19 +#define GPIO_INTERRUPT_STATUS_28_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_28_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_28_RESET 1 +#define GPIO_INTERRUPT_STATUS_27 18:18 +#define GPIO_INTERRUPT_STATUS_27_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_27_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_27_RESET 1 +#define GPIO_INTERRUPT_STATUS_26 17:17 +#define GPIO_INTERRUPT_STATUS_26_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_26_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_26_RESET 1 +#define GPIO_INTERRUPT_STATUS_25 16:16 +#define GPIO_INTERRUPT_STATUS_25_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_25_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_25_RESET 1 + + +#define PANEL_DISPLAY_CTRL 0x080000 +#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK 31:30 +#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK_DISABLE 0 +#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK_ENABLE 3 +#define PANEL_DISPLAY_CTRL_SELECT 29:28 +#define PANEL_DISPLAY_CTRL_SELECT_PANEL 0 +#define PANEL_DISPLAY_CTRL_SELECT_VGA 1 +#define PANEL_DISPLAY_CTRL_SELECT_CRT 2 +#define PANEL_DISPLAY_CTRL_FPEN 27:27 +#define PANEL_DISPLAY_CTRL_FPEN_LOW 0 +#define PANEL_DISPLAY_CTRL_FPEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_VBIASEN 26:26 +#define PANEL_DISPLAY_CTRL_VBIASEN_LOW 0 +#define PANEL_DISPLAY_CTRL_VBIASEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_DATA 25:25 +#define PANEL_DISPLAY_CTRL_DATA_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DATA_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FPVDDEN 24:24 +#define PANEL_DISPLAY_CTRL_FPVDDEN_LOW 0 +#define PANEL_DISPLAY_CTRL_FPVDDEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK 23:20 +#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK_DISABLE 0 +#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK_ENABLE 15 + +#define PANEL_DISPLAY_CTRL_TFT_DISP 19:18 +#define PANEL_DISPLAY_CTRL_TFT_DISP_24 0 +#define PANEL_DISPLAY_CTRL_TFT_DISP_36 1 +#define PANEL_DISPLAY_CTRL_TFT_DISP_18 2 + + +#define PANEL_DISPLAY_CTRL_DUAL_DISPLAY 19:19 +#define PANEL_DISPLAY_CTRL_DUAL_DISPLAY_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DUAL_DISPLAY_ENABLE 1 +#define PANEL_DISPLAY_CTRL_DOUBLE_PIXEL 18:18 +#define PANEL_DISPLAY_CTRL_DOUBLE_PIXEL_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DOUBLE_PIXEL_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FIFO 17:16 +#define PANEL_DISPLAY_CTRL_FIFO_1 0 +#define PANEL_DISPLAY_CTRL_FIFO_3 1 +#define PANEL_DISPLAY_CTRL_FIFO_7 2 +#define PANEL_DISPLAY_CTRL_FIFO_11 3 +#define PANEL_DISPLAY_CTRL_RESERVED_3_MASK 15:15 +#define PANEL_DISPLAY_CTRL_RESERVED_3_MASK_DISABLE 0 +#define PANEL_DISPLAY_CTRL_RESERVED_3_MASK_ENABLE 1 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE 14:14 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE 13:13 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE 12:12 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_VSYNC 11:11 +#define PANEL_DISPLAY_CTRL_VSYNC_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_VSYNC_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_CAPTURE_TIMING 10:10 +#define PANEL_DISPLAY_CTRL_CAPTURE_TIMING_DISABLE 0 +#define PANEL_DISPLAY_CTRL_CAPTURE_TIMING_ENABLE 1 +#define PANEL_DISPLAY_CTRL_COLOR_KEY 9:9 +#define PANEL_DISPLAY_CTRL_COLOR_KEY_DISABLE 0 +#define PANEL_DISPLAY_CTRL_COLOR_KEY_ENABLE 1 +#define PANEL_DISPLAY_CTRL_TIMING 8:8 +#define PANEL_DISPLAY_CTRL_TIMING_DISABLE 0 +#define PANEL_DISPLAY_CTRL_TIMING_ENABLE 1 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR 7:7 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR_DOWN 0 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR_UP 1 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN 6:6 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DISABLE 0 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_ENABLE 1 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR 5:5 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR_RIGHT 0 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR_LEFT 1 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN 4:4 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DISABLE 0 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_ENABLE 1 +#define PANEL_DISPLAY_CTRL_GAMMA 3:3 +#define PANEL_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define PANEL_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define PANEL_DISPLAY_CTRL_PLANE 2:2 +#define PANEL_DISPLAY_CTRL_PLANE_DISABLE 0 +#define PANEL_DISPLAY_CTRL_PLANE_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FORMAT 1:0 +#define PANEL_DISPLAY_CTRL_FORMAT_8 0 +#define PANEL_DISPLAY_CTRL_FORMAT_16 1 +#define PANEL_DISPLAY_CTRL_FORMAT_32 2 + +#define PANEL_PAN_CTRL 0x080004 +#define PANEL_PAN_CTRL_VERTICAL_PAN 31:24 +#define PANEL_PAN_CTRL_VERTICAL_VSYNC 21:16 +#define PANEL_PAN_CTRL_HORIZONTAL_PAN 15:8 +#define PANEL_PAN_CTRL_HORIZONTAL_VSYNC 5:0 + +#define PANEL_COLOR_KEY 0x080008 +#define PANEL_COLOR_KEY_MASK 31:16 +#define PANEL_COLOR_KEY_VALUE 15:0 + +#define PANEL_FB_ADDRESS 0x08000C +#define PANEL_FB_ADDRESS_STATUS 31:31 +#define PANEL_FB_ADDRESS_STATUS_CURRENT 0 +#define PANEL_FB_ADDRESS_STATUS_PENDING 1 +#define PANEL_FB_ADDRESS_EXT 27:27 +#define PANEL_FB_ADDRESS_EXT_LOCAL 0 +#define PANEL_FB_ADDRESS_EXT_EXTERNAL 1 +#define PANEL_FB_ADDRESS_ADDRESS 25:0 + +#define PANEL_FB_WIDTH 0x080010 +#define PANEL_FB_WIDTH_WIDTH 29:16 +#define PANEL_FB_WIDTH_OFFSET 13:0 + +#define PANEL_WINDOW_WIDTH 0x080014 +#define PANEL_WINDOW_WIDTH_WIDTH 27:16 +#define PANEL_WINDOW_WIDTH_X 11:0 + +#define PANEL_WINDOW_HEIGHT 0x080018 +#define PANEL_WINDOW_HEIGHT_HEIGHT 27:16 +#define PANEL_WINDOW_HEIGHT_Y 11:0 + +#define PANEL_PLANE_TL 0x08001C +#define PANEL_PLANE_TL_TOP 26:16 +#define PANEL_PLANE_TL_LEFT 10:0 + +#define PANEL_PLANE_BR 0x080020 +#define PANEL_PLANE_BR_BOTTOM 26:16 +#define PANEL_PLANE_BR_RIGHT 10:0 + +#define PANEL_HORIZONTAL_TOTAL 0x080024 +#define PANEL_HORIZONTAL_TOTAL_TOTAL 27:16 +#define PANEL_HORIZONTAL_TOTAL_DISPLAY_END 11:0 + +#define PANEL_HORIZONTAL_SYNC 0x080028 +#define PANEL_HORIZONTAL_SYNC_WIDTH 23:16 +#define PANEL_HORIZONTAL_SYNC_START 11:0 + +#define PANEL_VERTICAL_TOTAL 0x08002C +#define PANEL_VERTICAL_TOTAL_TOTAL 26:16 +#define PANEL_VERTICAL_TOTAL_DISPLAY_END 10:0 + +#define PANEL_VERTICAL_SYNC 0x080030 +#define PANEL_VERTICAL_SYNC_HEIGHT 21:16 +#define PANEL_VERTICAL_SYNC_START 10:0 + +#define PANEL_CURRENT_LINE 0x080034 +#define PANEL_CURRENT_LINE_LINE 10:0 + +/* Video Control */ + +#define VIDEO_DISPLAY_CTRL 0x080040 +#define VIDEO_DISPLAY_CTRL_LINE_BUFFER 18:18 +#define VIDEO_DISPLAY_CTRL_LINE_BUFFER_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_LINE_BUFFER_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_FIFO 17:16 +#define VIDEO_DISPLAY_CTRL_FIFO_1 0 +#define VIDEO_DISPLAY_CTRL_FIFO_3 1 +#define VIDEO_DISPLAY_CTRL_FIFO_7 2 +#define VIDEO_DISPLAY_CTRL_FIFO_11 3 +#define VIDEO_DISPLAY_CTRL_BUFFER 15:15 +#define VIDEO_DISPLAY_CTRL_BUFFER_0 0 +#define VIDEO_DISPLAY_CTRL_BUFFER_1 1 +#define VIDEO_DISPLAY_CTRL_CAPTURE 14:14 +#define VIDEO_DISPLAY_CTRL_CAPTURE_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_CAPTURE_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER 13:13 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP 12:12 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE 11:11 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE_NORMAL 0 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE_HALF 1 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE 10:10 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE_NORMAL 0 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE_HALF 1 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE 9:9 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE_REPLICATE 0 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE_INTERPOLATE 1 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE 8:8 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE_REPLICATE 0 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE_INTERPOLATE 1 +#define VIDEO_DISPLAY_CTRL_PIXEL 7:4 +#define VIDEO_DISPLAY_CTRL_GAMMA 3:3 +#define VIDEO_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_PLANE 2:2 +#define VIDEO_DISPLAY_CTRL_PLANE_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_PLANE_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_FORMAT 1:0 +#define VIDEO_DISPLAY_CTRL_FORMAT_8 0 +#define VIDEO_DISPLAY_CTRL_FORMAT_16 1 +#define VIDEO_DISPLAY_CTRL_FORMAT_32 2 +#define VIDEO_DISPLAY_CTRL_FORMAT_YUV 3 + +#define VIDEO_FB_0_ADDRESS 0x080044 +#define VIDEO_FB_0_ADDRESS_STATUS 31:31 +#define VIDEO_FB_0_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_FB_0_ADDRESS_STATUS_PENDING 1 +#define VIDEO_FB_0_ADDRESS_EXT 27:27 +#define VIDEO_FB_0_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_0_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_0_ADDRESS_ADDRESS 25:0 + +#define VIDEO_FB_WIDTH 0x080048 +#define VIDEO_FB_WIDTH_WIDTH 29:16 +#define VIDEO_FB_WIDTH_OFFSET 13:0 + +#define VIDEO_FB_0_LAST_ADDRESS 0x08004C +#define VIDEO_FB_0_LAST_ADDRESS_EXT 27:27 +#define VIDEO_FB_0_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_0_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_0_LAST_ADDRESS_ADDRESS 25:0 + +#define VIDEO_PLANE_TL 0x080050 +#define VIDEO_PLANE_TL_TOP 26:16 +#define VIDEO_PLANE_TL_LEFT 10:0 + +#define VIDEO_PLANE_BR 0x080054 +#define VIDEO_PLANE_BR_BOTTOM 26:16 +#define VIDEO_PLANE_BR_RIGHT 10:0 + +#define VIDEO_SCALE 0x080058 +#define VIDEO_SCALE_VERTICAL_MODE 31:31 +#define VIDEO_SCALE_VERTICAL_MODE_EXPAND 0 +#define VIDEO_SCALE_VERTICAL_MODE_SHRINK 1 +#define VIDEO_SCALE_VERTICAL_SCALE 27:16 +#define VIDEO_SCALE_HORIZONTAL_MODE 15:15 +#define VIDEO_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define VIDEO_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define VIDEO_SCALE_HORIZONTAL_SCALE 11:0 + +#define VIDEO_INITIAL_SCALE 0x08005C +#define VIDEO_INITIAL_SCALE_FB_1 27:16 +#define VIDEO_INITIAL_SCALE_FB_0 11:0 + +#define VIDEO_YUV_CONSTANTS 0x080060 +#define VIDEO_YUV_CONSTANTS_Y 31:24 +#define VIDEO_YUV_CONSTANTS_R 23:16 +#define VIDEO_YUV_CONSTANTS_G 15:8 +#define VIDEO_YUV_CONSTANTS_B 7:0 + +#define VIDEO_FB_1_ADDRESS 0x080064 +#define VIDEO_FB_1_ADDRESS_STATUS 31:31 +#define VIDEO_FB_1_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_FB_1_ADDRESS_STATUS_PENDING 1 +#define VIDEO_FB_1_ADDRESS_EXT 27:27 +#define VIDEO_FB_1_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_1_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_1_ADDRESS_ADDRESS 25:0 + +#define VIDEO_FB_1_LAST_ADDRESS 0x080068 +#define VIDEO_FB_1_LAST_ADDRESS_EXT 27:27 +#define VIDEO_FB_1_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_1_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_1_LAST_ADDRESS_ADDRESS 25:0 + +/* Video Alpha Control */ + +#define VIDEO_ALPHA_DISPLAY_CTRL 0x080080 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT 28:28 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT_PER_PIXEL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT_ALPHA 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_ALPHA 27:24 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO 17:16 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_1 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_3 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_7 2 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_11 3 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE 11:11 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE_NORMAL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE_HALF 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE 10:10 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE_NORMAL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE_HALF 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE 9:9 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE_REPLICATE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE_INTERPOLATE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE 8:8 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE_REPLICATE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE_INTERPOLATE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_PIXEL 7:4 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY 3:3 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY_DISABLE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY_ENABLE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE 2:2 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_DISABLE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_ENABLE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT 1:0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_8 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_16 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4 2 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4_4_4 3 + +#define VIDEO_ALPHA_FB_ADDRESS 0x080084 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS 31:31 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS_PENDING 1 +#define VIDEO_ALPHA_FB_ADDRESS_EXT 27:27 +#define VIDEO_ALPHA_FB_ADDRESS_EXT_LOCAL 0 +#define VIDEO_ALPHA_FB_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_ALPHA_FB_ADDRESS_ADDRESS 25:0 + +#define VIDEO_ALPHA_FB_WIDTH 0x080088 +#define VIDEO_ALPHA_FB_WIDTH_WIDTH 29:16 +#define VIDEO_ALPHA_FB_WIDTH_OFFSET 13:0 + +#define VIDEO_ALPHA_FB_LAST_ADDRESS 0x08008C +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT 27:27 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_ADDRESS 25:0 + +#define VIDEO_ALPHA_PLANE_TL 0x080090 +#define VIDEO_ALPHA_PLANE_TL_TOP 26:16 +#define VIDEO_ALPHA_PLANE_TL_LEFT 10:0 + +#define VIDEO_ALPHA_PLANE_BR 0x080094 +#define VIDEO_ALPHA_PLANE_BR_BOTTOM 26:16 +#define VIDEO_ALPHA_PLANE_BR_RIGHT 10:0 + +#define VIDEO_ALPHA_SCALE 0x080098 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE 31:31 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE_EXPAND 0 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE_SHRINK 1 +#define VIDEO_ALPHA_SCALE_VERTICAL_SCALE 27:16 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE 15:15 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_SCALE 11:0 + +#define VIDEO_ALPHA_INITIAL_SCALE 0x08009C +#define VIDEO_ALPHA_INITIAL_SCALE_VERTICAL 27:16 +#define VIDEO_ALPHA_INITIAL_SCALE_HORIZONTAL 11:0 + +#define VIDEO_ALPHA_CHROMA_KEY 0x0800A0 +#define VIDEO_ALPHA_CHROMA_KEY_MASK 31:16 +#define VIDEO_ALPHA_CHROMA_KEY_VALUE 15:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_01 0x0800A4 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_23 0x0800A8 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_45 0x0800AC +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_67 0x0800B0 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_89 0x0800B4 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_AB 0x0800B8 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_CD 0x0800BC +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_EF 0x0800C0 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_BLUE 4:0 + +/* Panel Cursor Control */ + +#define PANEL_HWC_ADDRESS 0x0800F0 +#define PANEL_HWC_ADDRESS_ENABLE 31:31 +#define PANEL_HWC_ADDRESS_ENABLE_DISABLE 0 +#define PANEL_HWC_ADDRESS_ENABLE_ENABLE 1 +#define PANEL_HWC_ADDRESS_EXT 27:27 +#define PANEL_HWC_ADDRESS_EXT_LOCAL 0 +#define PANEL_HWC_ADDRESS_EXT_EXTERNAL 1 +#define PANEL_HWC_ADDRESS_ADDRESS 25:0 + +#define PANEL_HWC_LOCATION 0x0800F4 +#define PANEL_HWC_LOCATION_TOP 27:27 +#define PANEL_HWC_LOCATION_TOP_INSIDE 0 +#define PANEL_HWC_LOCATION_TOP_OUTSIDE 1 +#define PANEL_HWC_LOCATION_Y 26:16 +#define PANEL_HWC_LOCATION_LEFT 11:11 +#define PANEL_HWC_LOCATION_LEFT_INSIDE 0 +#define PANEL_HWC_LOCATION_LEFT_OUTSIDE 1 +#define PANEL_HWC_LOCATION_X 10:0 + +#define PANEL_HWC_COLOR_12 0x0800F8 +#define PANEL_HWC_COLOR_12_2_RGB565 31:16 +#define PANEL_HWC_COLOR_12_1_RGB565 15:0 + +#define PANEL_HWC_COLOR_3 0x0800FC +#define PANEL_HWC_COLOR_3_RGB565 15:0 + +/* Old Definitions +++ */ +#define PANEL_HWC_COLOR_01 0x0800F8 +#define PANEL_HWC_COLOR_01_1_RED 31:27 +#define PANEL_HWC_COLOR_01_1_GREEN 26:21 +#define PANEL_HWC_COLOR_01_1_BLUE 20:16 +#define PANEL_HWC_COLOR_01_0_RED 15:11 +#define PANEL_HWC_COLOR_01_0_GREEN 10:5 +#define PANEL_HWC_COLOR_01_0_BLUE 4:0 + +#define PANEL_HWC_COLOR_2 0x0800FC +#define PANEL_HWC_COLOR_2_RED 15:11 +#define PANEL_HWC_COLOR_2_GREEN 10:5 +#define PANEL_HWC_COLOR_2_BLUE 4:0 +/* Old Definitions --- */ + +/* Alpha Control */ + +#define ALPHA_DISPLAY_CTRL 0x080100 +#define ALPHA_DISPLAY_CTRL_SELECT 28:28 +#define ALPHA_DISPLAY_CTRL_SELECT_PER_PIXEL 0 +#define ALPHA_DISPLAY_CTRL_SELECT_ALPHA 1 +#define ALPHA_DISPLAY_CTRL_ALPHA 27:24 +#define ALPHA_DISPLAY_CTRL_FIFO 17:16 +#define ALPHA_DISPLAY_CTRL_FIFO_1 0 +#define ALPHA_DISPLAY_CTRL_FIFO_3 1 +#define ALPHA_DISPLAY_CTRL_FIFO_7 2 +#define ALPHA_DISPLAY_CTRL_FIFO_11 3 +#define ALPHA_DISPLAY_CTRL_PIXEL 7:4 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY 3:3 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY_DISABLE 0 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY_ENABLE 1 +#define ALPHA_DISPLAY_CTRL_PLANE 2:2 +#define ALPHA_DISPLAY_CTRL_PLANE_DISABLE 0 +#define ALPHA_DISPLAY_CTRL_PLANE_ENABLE 1 +#define ALPHA_DISPLAY_CTRL_FORMAT 1:0 +#define ALPHA_DISPLAY_CTRL_FORMAT_16 1 +#define ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4 2 +#define ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4_4_4 3 + +#define ALPHA_FB_ADDRESS 0x080104 +#define ALPHA_FB_ADDRESS_STATUS 31:31 +#define ALPHA_FB_ADDRESS_STATUS_CURRENT 0 +#define ALPHA_FB_ADDRESS_STATUS_PENDING 1 +#define ALPHA_FB_ADDRESS_EXT 27:27 +#define ALPHA_FB_ADDRESS_EXT_LOCAL 0 +#define ALPHA_FB_ADDRESS_EXT_EXTERNAL 1 +#define ALPHA_FB_ADDRESS_ADDRESS 25:0 + +#define ALPHA_FB_WIDTH 0x080108 +#define ALPHA_FB_WIDTH_WIDTH 29:16 +#define ALPHA_FB_WIDTH_OFFSET 13:0 + +#define ALPHA_PLANE_TL 0x08010C +#define ALPHA_PLANE_TL_TOP 26:16 +#define ALPHA_PLANE_TL_LEFT 10:0 + +#define ALPHA_PLANE_BR 0x080110 +#define ALPHA_PLANE_BR_BOTTOM 26:16 +#define ALPHA_PLANE_BR_RIGHT 10:0 + +#define ALPHA_CHROMA_KEY 0x080114 +#define ALPHA_CHROMA_KEY_MASK 31:16 +#define ALPHA_CHROMA_KEY_VALUE 15:0 + +#define ALPHA_COLOR_LOOKUP_01 0x080118 +#define ALPHA_COLOR_LOOKUP_01_1 31:16 +#define ALPHA_COLOR_LOOKUP_01_1_RED 31:27 +#define ALPHA_COLOR_LOOKUP_01_1_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_01_1_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_01_0 15:0 +#define ALPHA_COLOR_LOOKUP_01_0_RED 15:11 +#define ALPHA_COLOR_LOOKUP_01_0_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_01_0_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_23 0x08011C +#define ALPHA_COLOR_LOOKUP_23_3 31:16 +#define ALPHA_COLOR_LOOKUP_23_3_RED 31:27 +#define ALPHA_COLOR_LOOKUP_23_3_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_23_3_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_23_2 15:0 +#define ALPHA_COLOR_LOOKUP_23_2_RED 15:11 +#define ALPHA_COLOR_LOOKUP_23_2_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_23_2_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_45 0x080120 +#define ALPHA_COLOR_LOOKUP_45_5 31:16 +#define ALPHA_COLOR_LOOKUP_45_5_RED 31:27 +#define ALPHA_COLOR_LOOKUP_45_5_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_45_5_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_45_4 15:0 +#define ALPHA_COLOR_LOOKUP_45_4_RED 15:11 +#define ALPHA_COLOR_LOOKUP_45_4_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_45_4_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_67 0x080124 +#define ALPHA_COLOR_LOOKUP_67_7 31:16 +#define ALPHA_COLOR_LOOKUP_67_7_RED 31:27 +#define ALPHA_COLOR_LOOKUP_67_7_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_67_7_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_67_6 15:0 +#define ALPHA_COLOR_LOOKUP_67_6_RED 15:11 +#define ALPHA_COLOR_LOOKUP_67_6_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_67_6_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_89 0x080128 +#define ALPHA_COLOR_LOOKUP_89_9 31:16 +#define ALPHA_COLOR_LOOKUP_89_9_RED 31:27 +#define ALPHA_COLOR_LOOKUP_89_9_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_89_9_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_89_8 15:0 +#define ALPHA_COLOR_LOOKUP_89_8_RED 15:11 +#define ALPHA_COLOR_LOOKUP_89_8_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_89_8_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_AB 0x08012C +#define ALPHA_COLOR_LOOKUP_AB_B 31:16 +#define ALPHA_COLOR_LOOKUP_AB_B_RED 31:27 +#define ALPHA_COLOR_LOOKUP_AB_B_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_AB_B_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_AB_A 15:0 +#define ALPHA_COLOR_LOOKUP_AB_A_RED 15:11 +#define ALPHA_COLOR_LOOKUP_AB_A_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_AB_A_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_CD 0x080130 +#define ALPHA_COLOR_LOOKUP_CD_D 31:16 +#define ALPHA_COLOR_LOOKUP_CD_D_RED 31:27 +#define ALPHA_COLOR_LOOKUP_CD_D_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_CD_D_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_CD_C 15:0 +#define ALPHA_COLOR_LOOKUP_CD_C_RED 15:11 +#define ALPHA_COLOR_LOOKUP_CD_C_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_CD_C_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_EF 0x080134 +#define ALPHA_COLOR_LOOKUP_EF_F 31:16 +#define ALPHA_COLOR_LOOKUP_EF_F_RED 31:27 +#define ALPHA_COLOR_LOOKUP_EF_F_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_EF_F_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_EF_E 15:0 +#define ALPHA_COLOR_LOOKUP_EF_E_RED 15:11 +#define ALPHA_COLOR_LOOKUP_EF_E_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_EF_E_BLUE 4:0 + +/* CRT Graphics Control */ + +#define CRT_DISPLAY_CTRL 0x080200 +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK 31:27 +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_DISABLE 0 +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_ENABLE 0x1F + +/* SM750LE definition */ +#define CRT_DISPLAY_CTRL_DPMS 31:30 +#define CRT_DISPLAY_CTRL_DPMS_0 0 +#define CRT_DISPLAY_CTRL_DPMS_1 1 +#define CRT_DISPLAY_CTRL_DPMS_2 2 +#define CRT_DISPLAY_CTRL_DPMS_3 3 +#define CRT_DISPLAY_CTRL_CLK 29:27 +#define CRT_DISPLAY_CTRL_CLK_PLL25 0 +#define CRT_DISPLAY_CTRL_CLK_PLL41 1 +#define CRT_DISPLAY_CTRL_CLK_PLL62 2 +#define CRT_DISPLAY_CTRL_CLK_PLL65 3 +#define CRT_DISPLAY_CTRL_CLK_PLL74 4 +#define CRT_DISPLAY_CTRL_CLK_PLL80 5 +#define CRT_DISPLAY_CTRL_CLK_PLL108 6 +#define CRT_DISPLAY_CTRL_CLK_RESERVED 7 +#define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC 26:26 +#define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC_DISABLE 1 +#define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC_ENABLE 0 + + +#define CRT_DISPLAY_CTRL_RESERVED_2_MASK 25:24 +#define CRT_DISPLAY_CTRL_RESERVED_2_MASK_ENABLE 3 +#define CRT_DISPLAY_CTRL_RESERVED_2_MASK_DISABLE 0 + +/* SM750LE definition */ +#define CRT_DISPLAY_CTRL_CRTSELECT 25:25 +#define CRT_DISPLAY_CTRL_CRTSELECT_VGA 0 +#define CRT_DISPLAY_CTRL_CRTSELECT_CRT 1 +#define CRT_DISPLAY_CTRL_RGBBIT 24:24 +#define CRT_DISPLAY_CTRL_RGBBIT_24BIT 0 +#define CRT_DISPLAY_CTRL_RGBBIT_12BIT 1 + + +#define CRT_DISPLAY_CTRL_RESERVED_3_MASK 15:15 +#define CRT_DISPLAY_CTRL_RESERVED_3_MASK_DISABLE 0 +#define CRT_DISPLAY_CTRL_RESERVED_3_MASK_ENABLE 1 + +#define CRT_DISPLAY_CTRL_RESERVED_4_MASK 9:9 +#define CRT_DISPLAY_CTRL_RESERVED_4_MASK_DISABLE 0 +#define CRT_DISPLAY_CTRL_RESERVED_4_MASK_ENABLE 1 + +#ifndef VALIDATION_CHIP + #define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC 26:26 + #define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC_DISABLE 1 + #define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC_ENABLE 0 + #define CRT_DISPLAY_CTRL_CENTERING 24:24 + #define CRT_DISPLAY_CTRL_CENTERING_DISABLE 0 + #define CRT_DISPLAY_CTRL_CENTERING_ENABLE 1 +#endif +#define CRT_DISPLAY_CTRL_LOCK_TIMING 23:23 +#define CRT_DISPLAY_CTRL_LOCK_TIMING_DISABLE 0 +#define CRT_DISPLAY_CTRL_LOCK_TIMING_ENABLE 1 +#define CRT_DISPLAY_CTRL_EXPANSION 22:22 +#define CRT_DISPLAY_CTRL_EXPANSION_DISABLE 0 +#define CRT_DISPLAY_CTRL_EXPANSION_ENABLE 1 +#define CRT_DISPLAY_CTRL_VERTICAL_MODE 21:21 +#define CRT_DISPLAY_CTRL_VERTICAL_MODE_REPLICATE 0 +#define CRT_DISPLAY_CTRL_VERTICAL_MODE_INTERPOLATE 1 +#define CRT_DISPLAY_CTRL_HORIZONTAL_MODE 20:20 +#define CRT_DISPLAY_CTRL_HORIZONTAL_MODE_REPLICATE 0 +#define CRT_DISPLAY_CTRL_HORIZONTAL_MODE_INTERPOLATE 1 +#define CRT_DISPLAY_CTRL_SELECT 19:18 +#define CRT_DISPLAY_CTRL_SELECT_PANEL 0 +#define CRT_DISPLAY_CTRL_SELECT_VGA 1 +#define CRT_DISPLAY_CTRL_SELECT_CRT 2 +#define CRT_DISPLAY_CTRL_FIFO 17:16 +#define CRT_DISPLAY_CTRL_FIFO_1 0 +#define CRT_DISPLAY_CTRL_FIFO_3 1 +#define CRT_DISPLAY_CTRL_FIFO_7 2 +#define CRT_DISPLAY_CTRL_FIFO_11 3 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE 14:14 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE 13:13 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE 12:12 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_BLANK 10:10 +#define CRT_DISPLAY_CTRL_BLANK_OFF 0 +#define CRT_DISPLAY_CTRL_BLANK_ON 1 +#define CRT_DISPLAY_CTRL_TIMING 8:8 +#define CRT_DISPLAY_CTRL_TIMING_DISABLE 0 +#define CRT_DISPLAY_CTRL_TIMING_ENABLE 1 +#define CRT_DISPLAY_CTRL_PIXEL 7:4 +#define CRT_DISPLAY_CTRL_GAMMA 3:3 +#define CRT_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define CRT_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define CRT_DISPLAY_CTRL_PLANE 2:2 +#define CRT_DISPLAY_CTRL_PLANE_DISABLE 0 +#define CRT_DISPLAY_CTRL_PLANE_ENABLE 1 +#define CRT_DISPLAY_CTRL_FORMAT 1:0 +#define CRT_DISPLAY_CTRL_FORMAT_8 0 +#define CRT_DISPLAY_CTRL_FORMAT_16 1 +#define CRT_DISPLAY_CTRL_FORMAT_32 2 +#define CRT_DISPLAY_CTRL_RESERVED_BITS_MASK 0xFF000200 + +#define CRT_FB_ADDRESS 0x080204 +#define CRT_FB_ADDRESS_STATUS 31:31 +#define CRT_FB_ADDRESS_STATUS_CURRENT 0 +#define CRT_FB_ADDRESS_STATUS_PENDING 1 +#define CRT_FB_ADDRESS_EXT 27:27 +#define CRT_FB_ADDRESS_EXT_LOCAL 0 +#define CRT_FB_ADDRESS_EXT_EXTERNAL 1 +#define CRT_FB_ADDRESS_ADDRESS 25:0 + +#define CRT_FB_WIDTH 0x080208 +#define CRT_FB_WIDTH_WIDTH 29:16 +#define CRT_FB_WIDTH_OFFSET 13:0 + +#define CRT_HORIZONTAL_TOTAL 0x08020C +#define CRT_HORIZONTAL_TOTAL_TOTAL 27:16 +#define CRT_HORIZONTAL_TOTAL_DISPLAY_END 11:0 + +#define CRT_HORIZONTAL_SYNC 0x080210 +#define CRT_HORIZONTAL_SYNC_WIDTH 23:16 +#define CRT_HORIZONTAL_SYNC_START 11:0 + +#define CRT_VERTICAL_TOTAL 0x080214 +#define CRT_VERTICAL_TOTAL_TOTAL 26:16 +#define CRT_VERTICAL_TOTAL_DISPLAY_END 10:0 + +#define CRT_VERTICAL_SYNC 0x080218 +#define CRT_VERTICAL_SYNC_HEIGHT 21:16 +#define CRT_VERTICAL_SYNC_START 10:0 + +#define CRT_SIGNATURE_ANALYZER 0x08021C +#define CRT_SIGNATURE_ANALYZER_STATUS 31:16 +#define CRT_SIGNATURE_ANALYZER_ENABLE 3:3 +#define CRT_SIGNATURE_ANALYZER_ENABLE_DISABLE 0 +#define CRT_SIGNATURE_ANALYZER_ENABLE_ENABLE 1 +#define CRT_SIGNATURE_ANALYZER_RESET 2:2 +#define CRT_SIGNATURE_ANALYZER_RESET_NORMAL 0 +#define CRT_SIGNATURE_ANALYZER_RESET_RESET 1 +#define CRT_SIGNATURE_ANALYZER_SOURCE 1:0 +#define CRT_SIGNATURE_ANALYZER_SOURCE_RED 0 +#define CRT_SIGNATURE_ANALYZER_SOURCE_GREEN 1 +#define CRT_SIGNATURE_ANALYZER_SOURCE_BLUE 2 + +#define CRT_CURRENT_LINE 0x080220 +#define CRT_CURRENT_LINE_LINE 10:0 + +#define CRT_MONITOR_DETECT 0x080224 +#define CRT_MONITOR_DETECT_VALUE 25:25 +#define CRT_MONITOR_DETECT_VALUE_DISABLE 0 +#define CRT_MONITOR_DETECT_VALUE_ENABLE 1 +#define CRT_MONITOR_DETECT_ENABLE 24:24 +#define CRT_MONITOR_DETECT_ENABLE_DISABLE 0 +#define CRT_MONITOR_DETECT_ENABLE_ENABLE 1 +#define CRT_MONITOR_DETECT_RED 23:16 +#define CRT_MONITOR_DETECT_GREEN 15:8 +#define CRT_MONITOR_DETECT_BLUE 7:0 + +#define CRT_SCALE 0x080228 +#define CRT_SCALE_VERTICAL_MODE 31:31 +#define CRT_SCALE_VERTICAL_MODE_EXPAND 0 +#define CRT_SCALE_VERTICAL_MODE_SHRINK 1 +#define CRT_SCALE_VERTICAL_SCALE 27:16 +#define CRT_SCALE_HORIZONTAL_MODE 15:15 +#define CRT_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define CRT_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define CRT_SCALE_HORIZONTAL_SCALE 11:0 + +/* CRT Cursor Control */ + +#define CRT_HWC_ADDRESS 0x080230 +#define CRT_HWC_ADDRESS_ENABLE 31:31 +#define CRT_HWC_ADDRESS_ENABLE_DISABLE 0 +#define CRT_HWC_ADDRESS_ENABLE_ENABLE 1 +#define CRT_HWC_ADDRESS_EXT 27:27 +#define CRT_HWC_ADDRESS_EXT_LOCAL 0 +#define CRT_HWC_ADDRESS_EXT_EXTERNAL 1 +#define CRT_HWC_ADDRESS_ADDRESS 25:0 + +#define CRT_HWC_LOCATION 0x080234 +#define CRT_HWC_LOCATION_TOP 27:27 +#define CRT_HWC_LOCATION_TOP_INSIDE 0 +#define CRT_HWC_LOCATION_TOP_OUTSIDE 1 +#define CRT_HWC_LOCATION_Y 26:16 +#define CRT_HWC_LOCATION_LEFT 11:11 +#define CRT_HWC_LOCATION_LEFT_INSIDE 0 +#define CRT_HWC_LOCATION_LEFT_OUTSIDE 1 +#define CRT_HWC_LOCATION_X 10:0 + +#define CRT_HWC_COLOR_12 0x080238 +#define CRT_HWC_COLOR_12_2_RGB565 31:16 +#define CRT_HWC_COLOR_12_1_RGB565 15:0 + +#define CRT_HWC_COLOR_3 0x08023C +#define CRT_HWC_COLOR_3_RGB565 15:0 + +/* Old Definitions +++. Need to be removed if no application use it. */ +#if 0 + #define CRT_HWC_COLOR_01 0x080238 + #define CRT_HWC_COLOR_01_1_RED 31:27 + #define CRT_HWC_COLOR_01_1_GREEN 26:21 + #define CRT_HWC_COLOR_01_1_BLUE 20:16 + #define CRT_HWC_COLOR_01_0_RED 15:11 + #define CRT_HWC_COLOR_01_0_GREEN 10:5 + #define CRT_HWC_COLOR_01_0_BLUE 4:0 + + #define CRT_HWC_COLOR_2 0x08023C + #define CRT_HWC_COLOR_2_RED 15:11 + #define CRT_HWC_COLOR_2_GREEN 10:5 + #define CRT_HWC_COLOR_2_BLUE 4:0 +#endif +/* Old Definitions --- */ + +/* This vertical expansion below start at 0x080240 ~ 0x080264 */ +#define CRT_VERTICAL_EXPANSION 0x080240 +#ifndef VALIDATION_CHIP + #define CRT_VERTICAL_CENTERING_VALUE 31:24 +#endif +#define CRT_VERTICAL_EXPANSION_COMPARE_VALUE 23:16 +#define CRT_VERTICAL_EXPANSION_LINE_BUFFER 15:12 +#define CRT_VERTICAL_EXPANSION_SCALE_FACTOR 11:0 + +/* This horizontal expansion below start at 0x080268 ~ 0x08027C */ +#define CRT_HORIZONTAL_EXPANSION 0x080268 +#ifndef VALIDATION_CHIP + #define CRT_HORIZONTAL_CENTERING_VALUE 31:24 +#endif +#define CRT_HORIZONTAL_EXPANSION_COMPARE_VALUE 23:16 +#define CRT_HORIZONTAL_EXPANSION_SCALE_FACTOR 11:0 + +#ifndef VALIDATION_CHIP + /* Auto Centering */ + #define CRT_AUTO_CENTERING_TL 0x080280 + #define CRT_AUTO_CENTERING_TL_TOP 26:16 + #define CRT_AUTO_CENTERING_TL_LEFT 10:0 + + #define CRT_AUTO_CENTERING_BR 0x080284 + #define CRT_AUTO_CENTERING_BR_BOTTOM 26:16 + #define CRT_AUTO_CENTERING_BR_RIGHT 10:0 +#endif + +/* sm750le new register to control panel output */ +#define DISPLAY_CONTROL_750LE 0x80288 +/* Palette RAM */ + +/* Panel Pallete register starts at 0x080400 ~ 0x0807FC */ +#define PANEL_PALETTE_RAM 0x080400 + +/* Panel Pallete register starts at 0x080C00 ~ 0x080FFC */ +#define CRT_PALETTE_RAM 0x080C00 + +/* 2D registers + * move their defination into general lynx_accel.h file + * because all smi graphic chip share the same drawing engine + * register format */ +#if 0 +#define DE_SOURCE 0x100000 +#define DE_SOURCE_WRAP 31:31 +#define DE_SOURCE_WRAP_DISABLE 0 +#define DE_SOURCE_WRAP_ENABLE 1 + +/* + * The following definitions are used in different setting + */ + +/* Use these definitions in XY addressing mode or linear addressing mode. */ +#define DE_SOURCE_X_K1 27:16 +#define DE_SOURCE_Y_K2 11:0 + +/* Use this definition in host write mode for mono. The Y_K2 is not used + in host write mode. */ +#define DE_SOURCE_X_K1_MONO 20:16 + +/* Use these definitions in Bresenham line drawing mode. */ +#define DE_SOURCE_X_K1_LINE 29:16 +#define DE_SOURCE_Y_K2_LINE 13:0 + +#define DE_DESTINATION 0x100004 +#define DE_DESTINATION_WRAP 31:31 +#define DE_DESTINATION_WRAP_DISABLE 0 +#define DE_DESTINATION_WRAP_ENABLE 1 +#if 1 + #define DE_DESTINATION_X 27:16 + #define DE_DESTINATION_Y 11:0 +#else + #define DE_DESTINATION_X 28:16 + #define DE_DESTINATION_Y 15:0 +#endif + +#define DE_DIMENSION 0x100008 +#define DE_DIMENSION_X 28:16 +#define DE_DIMENSION_Y_ET 15:0 + +#define DE_CONTROL 0x10000C +#define DE_CONTROL_STATUS 31:31 +#define DE_CONTROL_STATUS_STOP 0 +#define DE_CONTROL_STATUS_START 1 +#define DE_CONTROL_PATTERN 30:30 +#define DE_CONTROL_PATTERN_MONO 0 +#define DE_CONTROL_PATTERN_COLOR 1 +#define DE_CONTROL_UPDATE_DESTINATION_X 29:29 +#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0 +#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1 +#define DE_CONTROL_QUICK_START 28:28 +#define DE_CONTROL_QUICK_START_DISABLE 0 +#define DE_CONTROL_QUICK_START_ENABLE 1 +#define DE_CONTROL_DIRECTION 27:27 +#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0 +#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1 +#define DE_CONTROL_MAJOR 26:26 +#define DE_CONTROL_MAJOR_X 0 +#define DE_CONTROL_MAJOR_Y 1 +#define DE_CONTROL_STEP_X 25:25 +#define DE_CONTROL_STEP_X_POSITIVE 0 +#define DE_CONTROL_STEP_X_NEGATIVE 1 +#define DE_CONTROL_STEP_Y 24:24 +#define DE_CONTROL_STEP_Y_POSITIVE 0 +#define DE_CONTROL_STEP_Y_NEGATIVE 1 +#define DE_CONTROL_STRETCH 23:23 +#define DE_CONTROL_STRETCH_DISABLE 0 +#define DE_CONTROL_STRETCH_ENABLE 1 +#define DE_CONTROL_HOST 22:22 +#define DE_CONTROL_HOST_COLOR 0 +#define DE_CONTROL_HOST_MONO 1 +#define DE_CONTROL_LAST_PIXEL 21:21 +#define DE_CONTROL_LAST_PIXEL_OFF 0 +#define DE_CONTROL_LAST_PIXEL_ON 1 +#define DE_CONTROL_COMMAND 20:16 +#define DE_CONTROL_COMMAND_BITBLT 0 +#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1 +#define DE_CONTROL_COMMAND_DE_TILE 2 +#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3 +#define DE_CONTROL_COMMAND_ALPHA_BLEND 4 +#define DE_CONTROL_COMMAND_RLE_STRIP 5 +#define DE_CONTROL_COMMAND_SHORT_STROKE 6 +#define DE_CONTROL_COMMAND_LINE_DRAW 7 +#define DE_CONTROL_COMMAND_HOST_WRITE 8 +#define DE_CONTROL_COMMAND_HOST_READ 9 +#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10 +#define DE_CONTROL_COMMAND_ROTATE 11 +#define DE_CONTROL_COMMAND_FONT 12 +#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15 +#define DE_CONTROL_ROP_SELECT 15:15 +#define DE_CONTROL_ROP_SELECT_ROP3 0 +#define DE_CONTROL_ROP_SELECT_ROP2 1 +#define DE_CONTROL_ROP2_SOURCE 14:14 +#define DE_CONTROL_ROP2_SOURCE_BITMAP 0 +#define DE_CONTROL_ROP2_SOURCE_PATTERN 1 +#define DE_CONTROL_MONO_DATA 13:12 +#define DE_CONTROL_MONO_DATA_NOT_PACKED 0 +#define DE_CONTROL_MONO_DATA_8_PACKED 1 +#define DE_CONTROL_MONO_DATA_16_PACKED 2 +#define DE_CONTROL_MONO_DATA_32_PACKED 3 +#define DE_CONTROL_REPEAT_ROTATE 11:11 +#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0 +#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1 +#define DE_CONTROL_TRANSPARENCY_MATCH 10:10 +#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0 +#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1 +#define DE_CONTROL_TRANSPARENCY_SELECT 9:9 +#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0 +#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1 +#define DE_CONTROL_TRANSPARENCY 8:8 +#define DE_CONTROL_TRANSPARENCY_DISABLE 0 +#define DE_CONTROL_TRANSPARENCY_ENABLE 1 +#define DE_CONTROL_ROP 7:0 + +/* Pseudo fields. */ + +#define DE_CONTROL_SHORT_STROKE_DIR 27:24 +#define DE_CONTROL_SHORT_STROKE_DIR_225 0 +#define DE_CONTROL_SHORT_STROKE_DIR_135 1 +#define DE_CONTROL_SHORT_STROKE_DIR_315 2 +#define DE_CONTROL_SHORT_STROKE_DIR_45 3 +#define DE_CONTROL_SHORT_STROKE_DIR_270 4 +#define DE_CONTROL_SHORT_STROKE_DIR_90 5 +#define DE_CONTROL_SHORT_STROKE_DIR_180 8 +#define DE_CONTROL_SHORT_STROKE_DIR_0 10 +#define DE_CONTROL_ROTATION 25:24 +#define DE_CONTROL_ROTATION_0 0 +#define DE_CONTROL_ROTATION_270 1 +#define DE_CONTROL_ROTATION_90 2 +#define DE_CONTROL_ROTATION_180 3 + +#define DE_PITCH 0x100010 +#define DE_PITCH_DESTINATION 28:16 +#define DE_PITCH_SOURCE 12:0 + +#define DE_FOREGROUND 0x100014 +#define DE_FOREGROUND_COLOR 31:0 + +#define DE_BACKGROUND 0x100018 +#define DE_BACKGROUND_COLOR 31:0 + +#define DE_STRETCH_FORMAT 0x10001C +#define DE_STRETCH_FORMAT_PATTERN_XY 30:30 +#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0 +#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1 +#define DE_STRETCH_FORMAT_PATTERN_Y 29:27 +#define DE_STRETCH_FORMAT_PATTERN_X 25:23 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21:20 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2 +#define DE_STRETCH_FORMAT_ADDRESSING 19:16 +#define DE_STRETCH_FORMAT_ADDRESSING_XY 0 +#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15 +#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11:0 + +#define DE_COLOR_COMPARE 0x100020 +#define DE_COLOR_COMPARE_COLOR 23:0 + +#define DE_COLOR_COMPARE_MASK 0x100024 +#define DE_COLOR_COMPARE_MASK_MASKS 23:0 + +#define DE_MASKS 0x100028 +#define DE_MASKS_BYTE_MASK 31:16 +#define DE_MASKS_BIT_MASK 15:0 + +#define DE_CLIP_TL 0x10002C +#define DE_CLIP_TL_TOP 31:16 +#define DE_CLIP_TL_STATUS 13:13 +#define DE_CLIP_TL_STATUS_DISABLE 0 +#define DE_CLIP_TL_STATUS_ENABLE 1 +#define DE_CLIP_TL_INHIBIT 12:12 +#define DE_CLIP_TL_INHIBIT_OUTSIDE 0 +#define DE_CLIP_TL_INHIBIT_INSIDE 1 +#define DE_CLIP_TL_LEFT 11:0 + +#define DE_CLIP_BR 0x100030 +#define DE_CLIP_BR_BOTTOM 31:16 +#define DE_CLIP_BR_RIGHT 12:0 + +#define DE_MONO_PATTERN_LOW 0x100034 +#define DE_MONO_PATTERN_LOW_PATTERN 31:0 + +#define DE_MONO_PATTERN_HIGH 0x100038 +#define DE_MONO_PATTERN_HIGH_PATTERN 31:0 + +#define DE_WINDOW_WIDTH 0x10003C +#define DE_WINDOW_WIDTH_DESTINATION 28:16 +#define DE_WINDOW_WIDTH_SOURCE 12:0 + +#define DE_WINDOW_SOURCE_BASE 0x100040 +#define DE_WINDOW_SOURCE_BASE_EXT 27:27 +#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0 +#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1 +#define DE_WINDOW_SOURCE_BASE_CS 26:26 +#define DE_WINDOW_SOURCE_BASE_CS_0 0 +#define DE_WINDOW_SOURCE_BASE_CS_1 1 +#define DE_WINDOW_SOURCE_BASE_ADDRESS 25:0 + +#define DE_WINDOW_DESTINATION_BASE 0x100044 +#define DE_WINDOW_DESTINATION_BASE_EXT 27:27 +#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0 +#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1 +#define DE_WINDOW_DESTINATION_BASE_CS 26:26 +#define DE_WINDOW_DESTINATION_BASE_CS_0 0 +#define DE_WINDOW_DESTINATION_BASE_CS_1 1 +#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25:0 + +#define DE_ALPHA 0x100048 +#define DE_ALPHA_VALUE 7:0 + +#define DE_WRAP 0x10004C +#define DE_WRAP_X 31:16 +#define DE_WRAP_Y 15:0 + +#define DE_STATUS 0x100050 +#define DE_STATUS_CSC 1:1 +#define DE_STATUS_CSC_CLEAR 0 +#define DE_STATUS_CSC_NOT_ACTIVE 0 +#define DE_STATUS_CSC_ACTIVE 1 +#define DE_STATUS_2D 0:0 +#define DE_STATUS_2D_CLEAR 0 +#define DE_STATUS_2D_NOT_ACTIVE 0 +#define DE_STATUS_2D_ACTIVE 1 +#endif +/* Color Space Conversion registers. */ + +#define CSC_Y_SOURCE_BASE 0x1000C8 +#define CSC_Y_SOURCE_BASE_EXT 27:27 +#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_Y_SOURCE_BASE_CS 26:26 +#define CSC_Y_SOURCE_BASE_CS_0 0 +#define CSC_Y_SOURCE_BASE_CS_1 1 +#define CSC_Y_SOURCE_BASE_ADDRESS 25:0 + +#define CSC_CONSTANTS 0x1000CC +#define CSC_CONSTANTS_Y 31:24 +#define CSC_CONSTANTS_R 23:16 +#define CSC_CONSTANTS_G 15:8 +#define CSC_CONSTANTS_B 7:0 + +#define CSC_Y_SOURCE_X 0x1000D0 +#define CSC_Y_SOURCE_X_INTEGER 26:16 +#define CSC_Y_SOURCE_X_FRACTION 15:3 + +#define CSC_Y_SOURCE_Y 0x1000D4 +#define CSC_Y_SOURCE_Y_INTEGER 27:16 +#define CSC_Y_SOURCE_Y_FRACTION 15:3 + +#define CSC_U_SOURCE_BASE 0x1000D8 +#define CSC_U_SOURCE_BASE_EXT 27:27 +#define CSC_U_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_U_SOURCE_BASE_CS 26:26 +#define CSC_U_SOURCE_BASE_CS_0 0 +#define CSC_U_SOURCE_BASE_CS_1 1 +#define CSC_U_SOURCE_BASE_ADDRESS 25:0 + +#define CSC_V_SOURCE_BASE 0x1000DC +#define CSC_V_SOURCE_BASE_EXT 27:27 +#define CSC_V_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_V_SOURCE_BASE_CS 26:26 +#define CSC_V_SOURCE_BASE_CS_0 0 +#define CSC_V_SOURCE_BASE_CS_1 1 +#define CSC_V_SOURCE_BASE_ADDRESS 25:0 + +#define CSC_SOURCE_DIMENSION 0x1000E0 +#define CSC_SOURCE_DIMENSION_X 31:16 +#define CSC_SOURCE_DIMENSION_Y 15:0 + +#define CSC_SOURCE_PITCH 0x1000E4 +#define CSC_SOURCE_PITCH_Y 31:16 +#define CSC_SOURCE_PITCH_UV 15:0 + +#define CSC_DESTINATION 0x1000E8 +#define CSC_DESTINATION_WRAP 31:31 +#define CSC_DESTINATION_WRAP_DISABLE 0 +#define CSC_DESTINATION_WRAP_ENABLE 1 +#define CSC_DESTINATION_X 27:16 +#define CSC_DESTINATION_Y 11:0 + +#define CSC_DESTINATION_DIMENSION 0x1000EC +#define CSC_DESTINATION_DIMENSION_X 31:16 +#define CSC_DESTINATION_DIMENSION_Y 15:0 + +#define CSC_DESTINATION_PITCH 0x1000F0 +#define CSC_DESTINATION_PITCH_X 31:16 +#define CSC_DESTINATION_PITCH_Y 15:0 + +#define CSC_SCALE_FACTOR 0x1000F4 +#define CSC_SCALE_FACTOR_HORIZONTAL 31:16 +#define CSC_SCALE_FACTOR_VERTICAL 15:0 + +#define CSC_DESTINATION_BASE 0x1000F8 +#define CSC_DESTINATION_BASE_EXT 27:27 +#define CSC_DESTINATION_BASE_EXT_LOCAL 0 +#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1 +#define CSC_DESTINATION_BASE_CS 26:26 +#define CSC_DESTINATION_BASE_CS_0 0 +#define CSC_DESTINATION_BASE_CS_1 1 +#define CSC_DESTINATION_BASE_ADDRESS 25:0 + +#define CSC_CONTROL 0x1000FC +#define CSC_CONTROL_STATUS 31:31 +#define CSC_CONTROL_STATUS_STOP 0 +#define CSC_CONTROL_STATUS_START 1 +#define CSC_CONTROL_SOURCE_FORMAT 30:28 +#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0 +#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1 +#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2 +#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3 +#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4 +#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5 +#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6 +#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7 +#define CSC_CONTROL_DESTINATION_FORMAT 27:26 +#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0 +#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1 +#define CSC_CONTROL_HORIZONTAL_FILTER 25:25 +#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0 +#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1 +#define CSC_CONTROL_VERTICAL_FILTER 24:24 +#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0 +#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1 +#define CSC_CONTROL_BYTE_ORDER 23:23 +#define CSC_CONTROL_BYTE_ORDER_YUYV 0 +#define CSC_CONTROL_BYTE_ORDER_UYVY 1 + +#define DE_DATA_PORT 0x110000 + +#define I2C_BYTE_COUNT 0x010040 +#define I2C_BYTE_COUNT_COUNT 3:0 + +#define I2C_CTRL 0x010041 +#define I2C_CTRL_INT 4:4 +#define I2C_CTRL_INT_DISABLE 0 +#define I2C_CTRL_INT_ENABLE 1 +#define I2C_CTRL_DIR 3:3 +#define I2C_CTRL_DIR_WR 0 +#define I2C_CTRL_DIR_RD 1 +#define I2C_CTRL_CTRL 2:2 +#define I2C_CTRL_CTRL_STOP 0 +#define I2C_CTRL_CTRL_START 1 +#define I2C_CTRL_MODE 1:1 +#define I2C_CTRL_MODE_STANDARD 0 +#define I2C_CTRL_MODE_FAST 1 +#define I2C_CTRL_EN 0:0 +#define I2C_CTRL_EN_DISABLE 0 +#define I2C_CTRL_EN_ENABLE 1 + +#define I2C_STATUS 0x010042 +#define I2C_STATUS_TX 3:3 +#define I2C_STATUS_TX_PROGRESS 0 +#define I2C_STATUS_TX_COMPLETED 1 +#define I2C_TX_DONE 0x08 +#define I2C_STATUS_ERR 2:2 +#define I2C_STATUS_ERR_NORMAL 0 +#define I2C_STATUS_ERR_ERROR 1 +#define I2C_STATUS_ERR_CLEAR 0 +#define I2C_STATUS_ACK 1:1 +#define I2C_STATUS_ACK_RECEIVED 0 +#define I2C_STATUS_ACK_NOT 1 +#define I2C_STATUS_BSY 0:0 +#define I2C_STATUS_BSY_IDLE 0 +#define I2C_STATUS_BSY_BUSY 1 + +#define I2C_RESET 0x010042 +#define I2C_RESET_BUS_ERROR 2:2 +#define I2C_RESET_BUS_ERROR_CLEAR 0 + +#define I2C_SLAVE_ADDRESS 0x010043 +#define I2C_SLAVE_ADDRESS_ADDRESS 7:1 +#define I2C_SLAVE_ADDRESS_RW 0:0 +#define I2C_SLAVE_ADDRESS_RW_W 0 +#define I2C_SLAVE_ADDRESS_RW_R 1 + +#define I2C_DATA0 0x010044 +#define I2C_DATA1 0x010045 +#define I2C_DATA2 0x010046 +#define I2C_DATA3 0x010047 +#define I2C_DATA4 0x010048 +#define I2C_DATA5 0x010049 +#define I2C_DATA6 0x01004A +#define I2C_DATA7 0x01004B +#define I2C_DATA8 0x01004C +#define I2C_DATA9 0x01004D +#define I2C_DATA10 0x01004E +#define I2C_DATA11 0x01004F +#define I2C_DATA12 0x010050 +#define I2C_DATA13 0x010051 +#define I2C_DATA14 0x010052 +#define I2C_DATA15 0x010053 + + +#define ZV0_CAPTURE_CTRL 0x090000 +#define ZV0_CAPTURE_CTRL_FIELD_INPUT 27:27 +#define ZV0_CAPTURE_CTRL_FIELD_INPUT_EVEN_FIELD 0 +#define ZV0_CAPTURE_CTRL_FIELD_INPUT_ODD_FIELD 1 +#define ZV0_CAPTURE_CTRL_SCAN 26:26 +#define ZV0_CAPTURE_CTRL_SCAN_PROGRESSIVE 0 +#define ZV0_CAPTURE_CTRL_SCAN_INTERLACE 1 +#define ZV0_CAPTURE_CTRL_CURRENT_BUFFER 25:25 +#define ZV0_CAPTURE_CTRL_CURRENT_BUFFER_0 0 +#define ZV0_CAPTURE_CTRL_CURRENT_BUFFER_1 1 +#define ZV0_CAPTURE_CTRL_VERTICAL_SYNC 24:24 +#define ZV0_CAPTURE_CTRL_VERTICAL_SYNC_INACTIVE 0 +#define ZV0_CAPTURE_CTRL_VERTICAL_SYNC_ACTIVE 1 +#define ZV0_CAPTURE_CTRL_ADJ 19:19 +#define ZV0_CAPTURE_CTRL_ADJ_NORMAL 0 +#define ZV0_CAPTURE_CTRL_ADJ_DELAY 1 +#define ZV0_CAPTURE_CTRL_HA 18:18 +#define ZV0_CAPTURE_CTRL_HA_DISABLE 0 +#define ZV0_CAPTURE_CTRL_HA_ENABLE 1 +#define ZV0_CAPTURE_CTRL_VSK 17:17 +#define ZV0_CAPTURE_CTRL_VSK_DISABLE 0 +#define ZV0_CAPTURE_CTRL_VSK_ENABLE 1 +#define ZV0_CAPTURE_CTRL_HSK 16:16 +#define ZV0_CAPTURE_CTRL_HSK_DISABLE 0 +#define ZV0_CAPTURE_CTRL_HSK_ENABLE 1 +#define ZV0_CAPTURE_CTRL_FD 15:15 +#define ZV0_CAPTURE_CTRL_FD_RISING 0 +#define ZV0_CAPTURE_CTRL_FD_FALLING 1 +#define ZV0_CAPTURE_CTRL_VP 14:14 +#define ZV0_CAPTURE_CTRL_VP_HIGH 0 +#define ZV0_CAPTURE_CTRL_VP_LOW 1 +#define ZV0_CAPTURE_CTRL_HP 13:13 +#define ZV0_CAPTURE_CTRL_HP_HIGH 0 +#define ZV0_CAPTURE_CTRL_HP_LOW 1 +#define ZV0_CAPTURE_CTRL_CP 12:12 +#define ZV0_CAPTURE_CTRL_CP_HIGH 0 +#define ZV0_CAPTURE_CTRL_CP_LOW 1 +#define ZV0_CAPTURE_CTRL_UVS 11:11 +#define ZV0_CAPTURE_CTRL_UVS_DISABLE 0 +#define ZV0_CAPTURE_CTRL_UVS_ENABLE 1 +#define ZV0_CAPTURE_CTRL_BS 10:10 +#define ZV0_CAPTURE_CTRL_BS_DISABLE 0 +#define ZV0_CAPTURE_CTRL_BS_ENABLE 1 +#define ZV0_CAPTURE_CTRL_CS 9:9 +#define ZV0_CAPTURE_CTRL_CS_16 0 +#define ZV0_CAPTURE_CTRL_CS_8 1 +#define ZV0_CAPTURE_CTRL_CF 8:8 +#define ZV0_CAPTURE_CTRL_CF_YUV 0 +#define ZV0_CAPTURE_CTRL_CF_RGB 1 +#define ZV0_CAPTURE_CTRL_FS 7:7 +#define ZV0_CAPTURE_CTRL_FS_DISABLE 0 +#define ZV0_CAPTURE_CTRL_FS_ENABLE 1 +#define ZV0_CAPTURE_CTRL_WEAVE 6:6 +#define ZV0_CAPTURE_CTRL_WEAVE_DISABLE 0 +#define ZV0_CAPTURE_CTRL_WEAVE_ENABLE 1 +#define ZV0_CAPTURE_CTRL_BOB 5:5 +#define ZV0_CAPTURE_CTRL_BOB_DISABLE 0 +#define ZV0_CAPTURE_CTRL_BOB_ENABLE 1 +#define ZV0_CAPTURE_CTRL_DB 4:4 +#define ZV0_CAPTURE_CTRL_DB_DISABLE 0 +#define ZV0_CAPTURE_CTRL_DB_ENABLE 1 +#define ZV0_CAPTURE_CTRL_CC 3:3 +#define ZV0_CAPTURE_CTRL_CC_CONTINUE 0 +#define ZV0_CAPTURE_CTRL_CC_CONDITION 1 +#define ZV0_CAPTURE_CTRL_RGB 2:2 +#define ZV0_CAPTURE_CTRL_RGB_DISABLE 0 +#define ZV0_CAPTURE_CTRL_RGB_ENABLE 1 +#define ZV0_CAPTURE_CTRL_656 1:1 +#define ZV0_CAPTURE_CTRL_656_DISABLE 0 +#define ZV0_CAPTURE_CTRL_656_ENABLE 1 +#define ZV0_CAPTURE_CTRL_CAP 0:0 +#define ZV0_CAPTURE_CTRL_CAP_DISABLE 0 +#define ZV0_CAPTURE_CTRL_CAP_ENABLE 1 + +#define ZV0_CAPTURE_CLIP 0x090004 +#define ZV0_CAPTURE_CLIP_YCLIP_EVEN_FIELD 25:16 +#define ZV0_CAPTURE_CLIP_YCLIP 25:16 +#define ZV0_CAPTURE_CLIP_XCLIP 9:0 + +#define ZV0_CAPTURE_SIZE 0x090008 +#define ZV0_CAPTURE_SIZE_HEIGHT 26:16 +#define ZV0_CAPTURE_SIZE_WIDTH 10:0 + +#define ZV0_CAPTURE_BUF0_ADDRESS 0x09000C +#define ZV0_CAPTURE_BUF0_ADDRESS_STATUS 31:31 +#define ZV0_CAPTURE_BUF0_ADDRESS_STATUS_CURRENT 0 +#define ZV0_CAPTURE_BUF0_ADDRESS_STATUS_PENDING 1 +#define ZV0_CAPTURE_BUF0_ADDRESS_EXT 27:27 +#define ZV0_CAPTURE_BUF0_ADDRESS_EXT_LOCAL 0 +#define ZV0_CAPTURE_BUF0_ADDRESS_EXT_EXTERNAL 1 +#define ZV0_CAPTURE_BUF0_ADDRESS_CS 26:26 +#define ZV0_CAPTURE_BUF0_ADDRESS_CS_0 0 +#define ZV0_CAPTURE_BUF0_ADDRESS_CS_1 1 +#define ZV0_CAPTURE_BUF0_ADDRESS_ADDRESS 25:0 + +#define ZV0_CAPTURE_BUF1_ADDRESS 0x090010 +#define ZV0_CAPTURE_BUF1_ADDRESS_STATUS 31:31 +#define ZV0_CAPTURE_BUF1_ADDRESS_STATUS_CURRENT 0 +#define ZV0_CAPTURE_BUF1_ADDRESS_STATUS_PENDING 1 +#define ZV0_CAPTURE_BUF1_ADDRESS_EXT 27:27 +#define ZV0_CAPTURE_BUF1_ADDRESS_EXT_LOCAL 0 +#define ZV0_CAPTURE_BUF1_ADDRESS_EXT_EXTERNAL 1 +#define ZV0_CAPTURE_BUF1_ADDRESS_CS 26:26 +#define ZV0_CAPTURE_BUF1_ADDRESS_CS_0 0 +#define ZV0_CAPTURE_BUF1_ADDRESS_CS_1 1 +#define ZV0_CAPTURE_BUF1_ADDRESS_ADDRESS 25:0 + +#define ZV0_CAPTURE_BUF_OFFSET 0x090014 +#ifndef VALIDATION_CHIP + #define ZV0_CAPTURE_BUF_OFFSET_YCLIP_ODD_FIELD 25:16 +#endif +#define ZV0_CAPTURE_BUF_OFFSET_OFFSET 15:0 + +#define ZV0_CAPTURE_FIFO_CTRL 0x090018 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO 2:0 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_0 0 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_1 1 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_2 2 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_3 3 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_4 4 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_5 5 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_6 6 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_7 7 + +#define ZV0_CAPTURE_YRGB_CONST 0x09001C +#define ZV0_CAPTURE_YRGB_CONST_Y 31:24 +#define ZV0_CAPTURE_YRGB_CONST_R 23:16 +#define ZV0_CAPTURE_YRGB_CONST_G 15:8 +#define ZV0_CAPTURE_YRGB_CONST_B 7:0 + +#define ZV0_CAPTURE_LINE_COMP 0x090020 +#define ZV0_CAPTURE_LINE_COMP_LC 10:0 + +/* ZV1 */ + +#define ZV1_CAPTURE_CTRL 0x098000 +#define ZV1_CAPTURE_CTRL_FIELD_INPUT 27:27 +#define ZV1_CAPTURE_CTRL_FIELD_INPUT_EVEN_FIELD 0 +#define ZV1_CAPTURE_CTRL_FIELD_INPUT_ODD_FIELD 0 +#define ZV1_CAPTURE_CTRL_SCAN 26:26 +#define ZV1_CAPTURE_CTRL_SCAN_PROGRESSIVE 0 +#define ZV1_CAPTURE_CTRL_SCAN_INTERLACE 1 +#define ZV1_CAPTURE_CTRL_CURRENT_BUFFER 25:25 +#define ZV1_CAPTURE_CTRL_CURRENT_BUFFER_0 0 +#define ZV1_CAPTURE_CTRL_CURRENT_BUFFER_1 1 +#define ZV1_CAPTURE_CTRL_VERTICAL_SYNC 24:24 +#define ZV1_CAPTURE_CTRL_VERTICAL_SYNC_INACTIVE 0 +#define ZV1_CAPTURE_CTRL_VERTICAL_SYNC_ACTIVE 1 +#define ZV1_CAPTURE_CTRL_PANEL 20:20 +#define ZV1_CAPTURE_CTRL_PANEL_DISABLE 0 +#define ZV1_CAPTURE_CTRL_PANEL_ENABLE 1 +#define ZV1_CAPTURE_CTRL_ADJ 19:19 +#define ZV1_CAPTURE_CTRL_ADJ_NORMAL 0 +#define ZV1_CAPTURE_CTRL_ADJ_DELAY 1 +#define ZV1_CAPTURE_CTRL_HA 18:18 +#define ZV1_CAPTURE_CTRL_HA_DISABLE 0 +#define ZV1_CAPTURE_CTRL_HA_ENABLE 1 +#define ZV1_CAPTURE_CTRL_VSK 17:17 +#define ZV1_CAPTURE_CTRL_VSK_DISABLE 0 +#define ZV1_CAPTURE_CTRL_VSK_ENABLE 1 +#define ZV1_CAPTURE_CTRL_HSK 16:16 +#define ZV1_CAPTURE_CTRL_HSK_DISABLE 0 +#define ZV1_CAPTURE_CTRL_HSK_ENABLE 1 +#define ZV1_CAPTURE_CTRL_FD 15:15 +#define ZV1_CAPTURE_CTRL_FD_RISING 0 +#define ZV1_CAPTURE_CTRL_FD_FALLING 1 +#define ZV1_CAPTURE_CTRL_VP 14:14 +#define ZV1_CAPTURE_CTRL_VP_HIGH 0 +#define ZV1_CAPTURE_CTRL_VP_LOW 1 +#define ZV1_CAPTURE_CTRL_HP 13:13 +#define ZV1_CAPTURE_CTRL_HP_HIGH 0 +#define ZV1_CAPTURE_CTRL_HP_LOW 1 +#define ZV1_CAPTURE_CTRL_CP 12:12 +#define ZV1_CAPTURE_CTRL_CP_HIGH 0 +#define ZV1_CAPTURE_CTRL_CP_LOW 1 +#define ZV1_CAPTURE_CTRL_UVS 11:11 +#define ZV1_CAPTURE_CTRL_UVS_DISABLE 0 +#define ZV1_CAPTURE_CTRL_UVS_ENABLE 1 +#define ZV1_CAPTURE_CTRL_BS 10:10 +#define ZV1_CAPTURE_CTRL_BS_DISABLE 0 +#define ZV1_CAPTURE_CTRL_BS_ENABLE 1 +#define ZV1_CAPTURE_CTRL_CS 9:9 +#define ZV1_CAPTURE_CTRL_CS_16 0 +#define ZV1_CAPTURE_CTRL_CS_8 1 +#define ZV1_CAPTURE_CTRL_CF 8:8 +#define ZV1_CAPTURE_CTRL_CF_YUV 0 +#define ZV1_CAPTURE_CTRL_CF_RGB 1 +#define ZV1_CAPTURE_CTRL_FS 7:7 +#define ZV1_CAPTURE_CTRL_FS_DISABLE 0 +#define ZV1_CAPTURE_CTRL_FS_ENABLE 1 +#define ZV1_CAPTURE_CTRL_WEAVE 6:6 +#define ZV1_CAPTURE_CTRL_WEAVE_DISABLE 0 +#define ZV1_CAPTURE_CTRL_WEAVE_ENABLE 1 +#define ZV1_CAPTURE_CTRL_BOB 5:5 +#define ZV1_CAPTURE_CTRL_BOB_DISABLE 0 +#define ZV1_CAPTURE_CTRL_BOB_ENABLE 1 +#define ZV1_CAPTURE_CTRL_DB 4:4 +#define ZV1_CAPTURE_CTRL_DB_DISABLE 0 +#define ZV1_CAPTURE_CTRL_DB_ENABLE 1 +#define ZV1_CAPTURE_CTRL_CC 3:3 +#define ZV1_CAPTURE_CTRL_CC_CONTINUE 0 +#define ZV1_CAPTURE_CTRL_CC_CONDITION 1 +#define ZV1_CAPTURE_CTRL_RGB 2:2 +#define ZV1_CAPTURE_CTRL_RGB_DISABLE 0 +#define ZV1_CAPTURE_CTRL_RGB_ENABLE 1 +#define ZV1_CAPTURE_CTRL_656 1:1 +#define ZV1_CAPTURE_CTRL_656_DISABLE 0 +#define ZV1_CAPTURE_CTRL_656_ENABLE 1 +#define ZV1_CAPTURE_CTRL_CAP 0:0 +#define ZV1_CAPTURE_CTRL_CAP_DISABLE 0 +#define ZV1_CAPTURE_CTRL_CAP_ENABLE 1 + +#define ZV1_CAPTURE_CLIP 0x098004 +#define ZV1_CAPTURE_CLIP_YCLIP 25:16 +#define ZV1_CAPTURE_CLIP_XCLIP 9:0 + +#define ZV1_CAPTURE_SIZE 0x098008 +#define ZV1_CAPTURE_SIZE_HEIGHT 26:16 +#define ZV1_CAPTURE_SIZE_WIDTH 10:0 + +#define ZV1_CAPTURE_BUF0_ADDRESS 0x09800C +#define ZV1_CAPTURE_BUF0_ADDRESS_STATUS 31:31 +#define ZV1_CAPTURE_BUF0_ADDRESS_STATUS_CURRENT 0 +#define ZV1_CAPTURE_BUF0_ADDRESS_STATUS_PENDING 1 +#define ZV1_CAPTURE_BUF0_ADDRESS_EXT 27:27 +#define ZV1_CAPTURE_BUF0_ADDRESS_EXT_LOCAL 0 +#define ZV1_CAPTURE_BUF0_ADDRESS_EXT_EXTERNAL 1 +#define ZV1_CAPTURE_BUF0_ADDRESS_CS 26:26 +#define ZV1_CAPTURE_BUF0_ADDRESS_CS_0 0 +#define ZV1_CAPTURE_BUF0_ADDRESS_CS_1 1 +#define ZV1_CAPTURE_BUF0_ADDRESS_ADDRESS 25:0 + +#define ZV1_CAPTURE_BUF1_ADDRESS 0x098010 +#define ZV1_CAPTURE_BUF1_ADDRESS_STATUS 31:31 +#define ZV1_CAPTURE_BUF1_ADDRESS_STATUS_CURRENT 0 +#define ZV1_CAPTURE_BUF1_ADDRESS_STATUS_PENDING 1 +#define ZV1_CAPTURE_BUF1_ADDRESS_EXT 27:27 +#define ZV1_CAPTURE_BUF1_ADDRESS_EXT_LOCAL 0 +#define ZV1_CAPTURE_BUF1_ADDRESS_EXT_EXTERNAL 1 +#define ZV1_CAPTURE_BUF1_ADDRESS_CS 26:26 +#define ZV1_CAPTURE_BUF1_ADDRESS_CS_0 0 +#define ZV1_CAPTURE_BUF1_ADDRESS_CS_1 1 +#define ZV1_CAPTURE_BUF1_ADDRESS_ADDRESS 25:0 + +#define ZV1_CAPTURE_BUF_OFFSET 0x098014 +#define ZV1_CAPTURE_BUF_OFFSET_OFFSET 15:0 + +#define ZV1_CAPTURE_FIFO_CTRL 0x098018 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO 2:0 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_0 0 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_1 1 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_2 2 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_3 3 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_4 4 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_5 5 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_6 6 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_7 7 + +#define ZV1_CAPTURE_YRGB_CONST 0x09801C +#define ZV1_CAPTURE_YRGB_CONST_Y 31:24 +#define ZV1_CAPTURE_YRGB_CONST_R 23:16 +#define ZV1_CAPTURE_YRGB_CONST_G 15:8 +#define ZV1_CAPTURE_YRGB_CONST_B 7:0 + +#define DMA_1_SOURCE 0x0D0010 +#define DMA_1_SOURCE_ADDRESS_EXT 27:27 +#define DMA_1_SOURCE_ADDRESS_EXT_LOCAL 0 +#define DMA_1_SOURCE_ADDRESS_EXT_EXTERNAL 1 +#define DMA_1_SOURCE_ADDRESS_CS 26:26 +#define DMA_1_SOURCE_ADDRESS_CS_0 0 +#define DMA_1_SOURCE_ADDRESS_CS_1 1 +#define DMA_1_SOURCE_ADDRESS 25:0 + +#define DMA_1_DESTINATION 0x0D0014 +#define DMA_1_DESTINATION_ADDRESS_EXT 27:27 +#define DMA_1_DESTINATION_ADDRESS_EXT_LOCAL 0 +#define DMA_1_DESTINATION_ADDRESS_EXT_EXTERNAL 1 +#define DMA_1_DESTINATION_ADDRESS_CS 26:26 +#define DMA_1_DESTINATION_ADDRESS_CS_0 0 +#define DMA_1_DESTINATION_ADDRESS_CS_1 1 +#define DMA_1_DESTINATION_ADDRESS 25:0 + +#define DMA_1_SIZE_CONTROL 0x0D0018 +#define DMA_1_SIZE_CONTROL_STATUS 31:31 +#define DMA_1_SIZE_CONTROL_STATUS_IDLE 0 +#define DMA_1_SIZE_CONTROL_STATUS_ACTIVE 1 +#define DMA_1_SIZE_CONTROL_SIZE 23:0 + +#define DMA_ABORT_INTERRUPT 0x0D0020 +#define DMA_ABORT_INTERRUPT_ABORT_1 5:5 +#define DMA_ABORT_INTERRUPT_ABORT_1_ENABLE 0 +#define DMA_ABORT_INTERRUPT_ABORT_1_ABORT 1 +#define DMA_ABORT_INTERRUPT_ABORT_0 4:4 +#define DMA_ABORT_INTERRUPT_ABORT_0_ENABLE 0 +#define DMA_ABORT_INTERRUPT_ABORT_0_ABORT 1 +#define DMA_ABORT_INTERRUPT_INT_1 1:1 +#define DMA_ABORT_INTERRUPT_INT_1_CLEAR 0 +#define DMA_ABORT_INTERRUPT_INT_1_FINISHED 1 +#define DMA_ABORT_INTERRUPT_INT_0 0:0 +#define DMA_ABORT_INTERRUPT_INT_0_CLEAR 0 +#define DMA_ABORT_INTERRUPT_INT_0_FINISHED 1 + + + + + +/* Default i2c CLK and Data GPIO. These are the default i2c pins */ +#define DEFAULT_I2C_SCL 30 +#define DEFAULT_I2C_SDA 31 + + +#define GPIO_DATA_SM750LE 0x020018 +#define GPIO_DATA_SM750LE_1 1:1 +#define GPIO_DATA_SM750LE_0 0:0 + +#define GPIO_DATA_DIRECTION_SM750LE 0x02001C +#define GPIO_DATA_DIRECTION_SM750LE_1 1:1 +#define GPIO_DATA_DIRECTION_SM750LE_1_INPUT 0 +#define GPIO_DATA_DIRECTION_SM750LE_1_OUTPUT 1 +#define GPIO_DATA_DIRECTION_SM750LE_0 0:0 +#define GPIO_DATA_DIRECTION_SM750LE_0_INPUT 0 +#define GPIO_DATA_DIRECTION_SM750LE_0_OUTPUT 1 + + +#endif diff --git a/drivers/staging/sm750fb/ddk750_sii164.c b/drivers/staging/sm750fb/ddk750_sii164.c new file mode 100644 index 000000000000..faf825093e7f --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_sii164.c @@ -0,0 +1,425 @@ +#define USE_DVICHIP +#ifdef USE_DVICHIP + +#include "ddk750_sii164.h" +#include "ddk750_hwi2c.h" + +/* I2C Address of each SII164 chip */ +#define SII164_I2C_ADDRESS 0x70 + +/* Define this definition to use hardware i2c. */ +#define USE_HW_I2C + +#ifdef USE_HW_I2C + #define i2cWriteReg hwI2CWriteReg + #define i2cReadReg hwI2CReadReg +#else + #define i2cWriteReg swI2CWriteReg + #define i2cReadReg swI2CReadReg +#endif + +/* SII164 Vendor and Device ID */ +#define SII164_VENDOR_ID 0x0001 +#define SII164_DEVICE_ID 0x0006 + +#ifdef SII164_FULL_FUNCTIONS +/* Name of the DVI Controller chip */ +static char *gDviCtrlChipName = "Silicon Image SiI 164"; +#endif + +/* + * sii164GetVendorID + * This function gets the vendor ID of the DVI controller chip. + * + * Output: + * Vendor ID + */ +unsigned short sii164GetVendorID() +{ + unsigned short vendorID; + + vendorID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_HIGH) << 8) | + (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_LOW); + + return vendorID; +} + +/* + * sii164GetDeviceID + * This function gets the device ID of the DVI controller chip. + * + * Output: + * Device ID + */ +unsigned short sii164GetDeviceID() +{ + unsigned short deviceID; + + deviceID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_HIGH) << 8) | + (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_LOW); + + return deviceID; +} + + + +/* DVI.C will handle all SiI164 chip stuffs and try it best to make code minimal and useful */ + +/* + * sii164InitChip + * This function initialize and detect the DVI controller chip. + * + * Input: + * edgeSelect - Edge Select: + * 0 = Input data is falling edge latched (falling edge + * latched first in dual edge mode) + * 1 = Input data is rising edge latched (rising edge + * latched first in dual edge mode) + * busSelect - Input Bus Select: + * 0 = Input data bus is 12-bits wide + * 1 = Input data bus is 24-bits wide + * dualEdgeClkSelect - Dual Edge Clock Select + * 0 = Input data is single edge latched + * 1 = Input data is dual edge latched + * hsyncEnable - Horizontal Sync Enable: + * 0 = HSYNC input is transmitted as fixed LOW + * 1 = HSYNC input is transmitted as is + * vsyncEnable - Vertical Sync Enable: + * 0 = VSYNC input is transmitted as fixed LOW + * 1 = VSYNC input is transmitted as is + * deskewEnable - De-skewing Enable: + * 0 = De-skew disabled + * 1 = De-skew enabled + * deskewSetting - De-skewing Setting (increment of 260psec) + * 0 = 1 step --> minimum setup / maximum hold + * 1 = 2 step + * 2 = 3 step + * 3 = 4 step + * 4 = 5 step + * 5 = 6 step + * 6 = 7 step + * 7 = 8 step --> maximum setup / minimum hold + * continuousSyncEnable- SYNC Continuous: + * 0 = Disable + * 1 = Enable + * pllFilterEnable - PLL Filter Enable + * 0 = Disable PLL Filter + * 1 = Enable PLL Filter + * pllFilterValue - PLL Filter characteristics: + * 0~7 (recommended value is 4) + * + * Output: + * 0 - Success + * -1 - Fail. + */ +long sii164InitChip( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue +) +{ + //unsigned char ucRegIndex, ucRegValue; + //unsigned char ucDeviceAddress, + unsigned char config; + //unsigned long delayCount; + + /* Initialize the i2c bus */ +#ifdef USE_HW_I2C + /* Use fast mode. */ + hwI2CInit(1); +#else + swI2CInit(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA); +#endif + + /* Check if SII164 Chip exists */ + if ((sii164GetVendorID() == SII164_VENDOR_ID) && (sii164GetDeviceID() == SII164_DEVICE_ID)) + { + +#ifdef DDKDEBUG + //sii164PrintRegisterValues(); +#endif + /* + * Initialize SII164 controller chip. + */ + + /* Select the edge */ + if (edgeSelect == 0) + config = SII164_CONFIGURATION_LATCH_FALLING; + else + config = SII164_CONFIGURATION_LATCH_RISING; + + /* Select bus wide */ + if (busSelect == 0) + config |= SII164_CONFIGURATION_BUS_12BITS; + else + config |= SII164_CONFIGURATION_BUS_24BITS; + + /* Select Dual/Single Edge Clock */ + if (dualEdgeClkSelect == 0) + config |= SII164_CONFIGURATION_CLOCK_SINGLE; + else + config |= SII164_CONFIGURATION_CLOCK_DUAL; + + /* Select HSync Enable */ + if (hsyncEnable == 0) + config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW; + else + config |= SII164_CONFIGURATION_HSYNC_AS_IS; + + /* Select VSync Enable */ + if (vsyncEnable == 0) + config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW; + else + config |= SII164_CONFIGURATION_VSYNC_AS_IS; + + i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); + + /* De-skew enabled with default 111b value. + This will fix some artifacts problem in some mode on board 2.2. + Somehow this fix does not affect board 2.1. + */ + if (deskewEnable == 0) + config = SII164_DESKEW_DISABLE; + else + config = SII164_DESKEW_ENABLE; + + switch (deskewSetting) + { + case 0: + config |= SII164_DESKEW_1_STEP; + break; + case 1: + config |= SII164_DESKEW_2_STEP; + break; + case 2: + config |= SII164_DESKEW_3_STEP; + break; + case 3: + config |= SII164_DESKEW_4_STEP; + break; + case 4: + config |= SII164_DESKEW_5_STEP; + break; + case 5: + config |= SII164_DESKEW_6_STEP; + break; + case 6: + config |= SII164_DESKEW_7_STEP; + break; + case 7: + config |= SII164_DESKEW_8_STEP; + break; + } + i2cWriteReg(SII164_I2C_ADDRESS, SII164_DESKEW, config); + + /* Enable/Disable Continuous Sync. */ + if (continuousSyncEnable == 0) + config = SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE; + else + config = SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE; + + /* Enable/Disable PLL Filter */ + if (pllFilterEnable == 0) + config |= SII164_PLL_FILTER_DISABLE; + else + config |= SII164_PLL_FILTER_ENABLE; + + /* Set the PLL Filter value */ + config |= ((pllFilterValue & 0x07) << 1); + + i2cWriteReg(SII164_I2C_ADDRESS, SII164_PLL, config); + + /* Recover from Power Down and enable output. */ + config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION); + config |= SII164_CONFIGURATION_POWER_NORMAL; + i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); + +#ifdef DDKDEBUG + //sii164PrintRegisterValues(); +#endif + + return 0; + } + + /* Return -1 if initialization fails. */ + return (-1); +} + + + + + +/* below sii164 function is not neccessary */ + +#ifdef SII164_FULL_FUNCTIONS + +/* + * sii164ResetChip + * This function resets the DVI Controller Chip. + */ +void sii164ResetChip() +{ + /* Power down */ + sii164SetPower(0); + sii164SetPower(1); +} + + +/* + * sii164GetChipString + * This function returns a char string name of the current DVI Controller chip. + * It's convenient for application need to display the chip name. + */ +char *sii164GetChipString() +{ + return gDviCtrlChipName; +} + + +/* + * sii164SetPower + * This function sets the power configuration of the DVI Controller Chip. + * + * Input: + * powerUp - Flag to set the power down or up + */ +void sii164SetPower( + unsigned char powerUp +) +{ + unsigned char config; + + config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION); + if (powerUp == 1) + { + /* Power up the chip */ + config &= ~SII164_CONFIGURATION_POWER_MASK; + config |= SII164_CONFIGURATION_POWER_NORMAL; + i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); + } + else + { + /* Power down the chip */ + config &= ~SII164_CONFIGURATION_POWER_MASK; + config |= SII164_CONFIGURATION_POWER_DOWN; + i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); + } +} + + +/* + * sii164SelectHotPlugDetectionMode + * This function selects the mode of the hot plug detection. + */ +static void sii164SelectHotPlugDetectionMode( + sii164_hot_plug_mode_t hotPlugMode +) +{ + unsigned char detectReg; + + detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG; + switch (hotPlugMode) + { + case SII164_HOTPLUG_DISABLE: + detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH; + break; + case SII164_HOTPLUG_USE_MDI: + detectReg &= ~SII164_DETECT_INTERRUPT_MASK; + detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN; + detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI; + break; + case SII164_HOTPLUG_USE_RSEN: + detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN; + break; + case SII164_HOTPLUG_USE_HTPLG: + detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG; + break; + } + + i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg); +} + +/* + * sii164EnableHotPlugDetection + * This function enables the Hot Plug detection. + * + * enableHotPlug - Enable (=1) / disable (=0) Hot Plug detection + */ +void sii164EnableHotPlugDetection( + unsigned char enableHotPlug +) +{ + unsigned char detectReg; + detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT); + + /* Depending on each DVI controller, need to enable the hot plug based on each + individual chip design. */ + if (enableHotPlug != 0) + sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI); + else + sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE); +} + +/* + * sii164IsConnected + * Check if the DVI Monitor is connected. + * + * Output: + * 0 - Not Connected + * 1 - Connected + */ +unsigned char sii164IsConnected() +{ + unsigned char hotPlugValue; + + hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_HOT_PLUG_STATUS_MASK; + if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON) + return 1; + else + return 0; +} + +/* + * sii164CheckInterrupt + * Checks if interrupt has occured. + * + * Output: + * 0 - No interrupt + * 1 - Interrupt occurs + */ +unsigned char sii164CheckInterrupt() +{ + unsigned char detectReg; + + detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_MONITOR_STATE_MASK; + if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE) + return 1; + else + return 0; +} + +/* + * sii164ClearInterrupt + * Clear the hot plug interrupt. + */ +void sii164ClearInterrupt() +{ + unsigned char detectReg; + + /* Clear the MDI interrupt */ + detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT); + i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg | SII164_DETECT_MONITOR_STATE_CLEAR); +} + +#endif + +#endif + + diff --git a/drivers/staging/sm750fb/ddk750_sii164.h b/drivers/staging/sm750fb/ddk750_sii164.h new file mode 100644 index 000000000000..2b4c7d3381df --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_sii164.h @@ -0,0 +1,172 @@ +#ifndef DDK750_SII164_H__ +#define DDK750_SII164_H__ + +#define USE_DVICHIP + +/* Hot Plug detection mode structure */ +typedef enum _sii164_hot_plug_mode_t +{ + SII164_HOTPLUG_DISABLE = 0, /* Disable Hot Plug output bit (always high). */ + SII164_HOTPLUG_USE_MDI, /* Use Monitor Detect Interrupt bit. */ + SII164_HOTPLUG_USE_RSEN, /* Use Receiver Sense detect bit. */ + SII164_HOTPLUG_USE_HTPLG /* Use Hot Plug detect bit. */ +} sii164_hot_plug_mode_t; + + +/* Silicon Image SiI164 chip prototype */ +long sii164InitChip( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue +); + +unsigned short sii164GetVendorID(void); +unsigned short sii164GetDeviceID(void); + + +#ifdef SII164_FULL_FUNCTIONS +void sii164ResetChip(void); +char *sii164GetChipString(void); +void sii164SetPower(unsigned char powerUp); +void sii164EnableHotPlugDetection(unsigned char enableHotPlug); +unsigned char sii164IsConnected(void); +unsigned char sii164CheckInterrupt(void); +void sii164ClearInterrupt(void); +#endif +/* below register definination is used for Silicon Image SiI164 DVI controller chip */ +/* + * Vendor ID registers + */ +#define SII164_VENDOR_ID_LOW 0x00 +#define SII164_VENDOR_ID_HIGH 0x01 + +/* + * Device ID registers + */ +#define SII164_DEVICE_ID_LOW 0x02 +#define SII164_DEVICE_ID_HIGH 0x03 + +/* + * Device Revision + */ +#define SII164_DEVICE_REVISION 0x04 + +/* + * Frequency Limitation registers + */ +#define SII164_FREQUENCY_LIMIT_LOW 0x06 +#define SII164_FREQUENCY_LIMIT_HIGH 0x07 + +/* + * Power Down and Input Signal Configuration registers + */ +#define SII164_CONFIGURATION 0x08 + +/* Power down (PD) */ +#define SII164_CONFIGURATION_POWER_DOWN 0x00 +#define SII164_CONFIGURATION_POWER_NORMAL 0x01 +#define SII164_CONFIGURATION_POWER_MASK 0x01 + +/* Input Edge Latch Select (EDGE) */ +#define SII164_CONFIGURATION_LATCH_FALLING 0x00 +#define SII164_CONFIGURATION_LATCH_RISING 0x02 + +/* Bus Select (BSEL) */ +#define SII164_CONFIGURATION_BUS_12BITS 0x00 +#define SII164_CONFIGURATION_BUS_24BITS 0x04 + +/* Dual Edge Clock Select (DSEL) */ +#define SII164_CONFIGURATION_CLOCK_SINGLE 0x00 +#define SII164_CONFIGURATION_CLOCK_DUAL 0x08 + +/* Horizontal Sync Enable (HEN) */ +#define SII164_CONFIGURATION_HSYNC_FORCE_LOW 0x00 +#define SII164_CONFIGURATION_HSYNC_AS_IS 0x10 + +/* Vertical Sync Enable (VEN) */ +#define SII164_CONFIGURATION_VSYNC_FORCE_LOW 0x00 +#define SII164_CONFIGURATION_VSYNC_AS_IS 0x20 + +/* + * Detection registers + */ +#define SII164_DETECT 0x09 + +/* Monitor Detect Interrupt (MDI) */ +#define SII164_DETECT_MONITOR_STATE_CHANGE 0x00 +#define SII164_DETECT_MONITOR_STATE_NO_CHANGE 0x01 +#define SII164_DETECT_MONITOR_STATE_CLEAR 0x01 +#define SII164_DETECT_MONITOR_STATE_MASK 0x01 + +/* Hot Plug detect Input (HTPLG) */ +#define SII164_DETECT_HOT_PLUG_STATUS_OFF 0x00 +#define SII164_DETECT_HOT_PLUG_STATUS_ON 0x02 +#define SII164_DETECT_HOT_PLUG_STATUS_MASK 0x02 + +/* Receiver Sense (RSEN) */ +#define SII164_DETECT_RECEIVER_SENSE_NOT_DETECTED 0x00 +#define SII164_DETECT_RECEIVER_SENSE_DETECTED 0x04 + +/* Interrupt Generation Method (TSEL) */ +#define SII164_DETECT_INTERRUPT_BY_RSEN_PIN 0x00 +#define SII164_DETECT_INTERRUPT_BY_HTPLG_PIN 0x08 +#define SII164_DETECT_INTERRUPT_MASK 0x08 + +/* Monitor Sense Output (MSEN) */ +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH 0x00 +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI 0x10 +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN 0x20 +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG 0x30 +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG 0x30 + +/* + * Skewing registers + */ +#define SII164_DESKEW 0x0A + +/* General Purpose Input (CTL[3:1]) */ +#define SII164_DESKEW_GENERAL_PURPOSE_INPUT_MASK 0x0E + +/* De-skewing Enable bit (DKEN) */ +#define SII164_DESKEW_DISABLE 0x00 +#define SII164_DESKEW_ENABLE 0x10 + +/* De-skewing Setting (DK[3:1])*/ +#define SII164_DESKEW_1_STEP 0x00 +#define SII164_DESKEW_2_STEP 0x20 +#define SII164_DESKEW_3_STEP 0x40 +#define SII164_DESKEW_4_STEP 0x60 +#define SII164_DESKEW_5_STEP 0x80 +#define SII164_DESKEW_6_STEP 0xA0 +#define SII164_DESKEW_7_STEP 0xC0 +#define SII164_DESKEW_8_STEP 0xE0 + +/* + * User Configuration Data registers (CFG 7:0) + */ +#define SII164_USER_CONFIGURATION 0x0B + +/* + * PLL registers + */ +#define SII164_PLL 0x0C + +/* PLL Filter Value (PLLF) */ +#define SII164_PLL_FILTER_VALUE_MASK 0x0E + +/* PLL Filter Enable (PFEN) */ +#define SII164_PLL_FILTER_DISABLE 0x00 +#define SII164_PLL_FILTER_ENABLE 0x01 + +/* Sync Continuous (SCNT) */ +#define SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE 0x00 +#define SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE 0x80 + +#endif diff --git a/drivers/staging/sm750fb/ddk750_swi2c.c b/drivers/staging/sm750fb/ddk750_swi2c.c new file mode 100644 index 000000000000..b53407bb2042 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_swi2c.c @@ -0,0 +1,535 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* swi2c.c --- SM750/SM718 DDK +* This file contains the source code for I2C using software +* implementation. +* +*******************************************************************/ +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_swi2c.h" +#include "ddk750_power.h" + + +/******************************************************************* + * I2C Software Master Driver: + * =========================== + * Each i2c cycle is split into 4 sections. Each of these section marks + * a point in time where the SCL or SDA may be changed. + * + * 1 Cycle == | Section I. | Section 2. | Section 3. | Section 4. | + * +-------------+-------------+-------------+-------------+ + * | SCL set LOW |SCL no change| SCL set HIGH|SCL no change| + * + * ____________ _____________ + * SCL == XXXX _____________ ____________ / + * + * I.e. the SCL may only be changed in section 1. and section 3. while + * the SDA may only be changed in section 2. and section 4. The table + * below gives the changes for these 2 lines in the varios sections. + * + * Section changes Table: + * ====================== + * blank = no change, L = set bit LOW, H = set bit HIGH + * + * | 1.| 2.| 3.| 4.| + * ---------------+---+---+---+---+ + * Tx Start SDA | | H | | L | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * Tx Stop SDA | | L | | H | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * Tx bit H SDA | | H | | | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * Tx bit L SDA | | L | | | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * + ******************************************************************/ + +/* GPIO pins used for this I2C. It ranges from 0 to 63. */ +static unsigned char g_i2cClockGPIO = DEFAULT_I2C_SCL; +static unsigned char g_i2cDataGPIO = DEFAULT_I2C_SDA; + +/* + * Below is the variable declaration for the GPIO pin register usage + * for the i2c Clock and i2c Data. + * + * Note: + * Notice that the GPIO usage for the i2c clock and i2c Data are + * separated. This is to make this code flexible enough when + * two separate GPIO pins for the clock and data are located + * in two different GPIO register set (worst case). + */ + +/* i2c Clock GPIO Register usage */ +static unsigned long g_i2cClkGPIOMuxReg = GPIO_MUX; +static unsigned long g_i2cClkGPIODataReg = GPIO_DATA; +static unsigned long g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION; + +/* i2c Data GPIO Register usage */ +static unsigned long g_i2cDataGPIOMuxReg = GPIO_MUX; +static unsigned long g_i2cDataGPIODataReg = GPIO_DATA; +static unsigned long g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION; + +static unsigned char peekIO(unsigned short port,unsigned short index) +{ +#if defined(__i386__) || defined( __x86_64__) + outb_p(index,port); + return inb_p(port+1); +#endif +} + +/* + * This function puts a delay between command + */ +static void swI2CWait(void) +{ + /* find a bug: + * peekIO method works well before suspend/resume + * but after suspend, peekIO(0x3ce,0x61) & 0x10 + * always be non-zero,which makes the while loop + * never finish. + * use non-ultimate for loop below is safe + * */ +#if 0 + /* Change wait algorithm to use PCI bus clock, + it's more reliable than counter loop .. + write 0x61 to 0x3ce and read from 0x3cf + */ + while(peekIO(0x3ce,0x61) & 0x10); +#else + int i, Temp; + + for(i=0; i<600; i++) + { + Temp = i; + Temp += i; + } +#endif +} + +/* + * This function set/reset the SCL GPIO pin + * + * Parameters: + * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + * + * Notes: + * When setting SCL to high, just set the GPIO as input where the pull up + * resistor will pull the signal up. Do not use software to pull up the + * signal because the i2c will fail when other device try to drive the + * signal due to SM50x will drive the signal to always high. + */ +void swI2CSCL(unsigned char value) +{ + unsigned long ulGPIOData; + unsigned long ulGPIODirection; + + ulGPIODirection = PEEK32(g_i2cClkGPIODataDirReg); + if (value) /* High */ + { + /* Set direction as input. This will automatically pull the signal up. */ + ulGPIODirection &= ~(1 << g_i2cClockGPIO); + POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection); + } + else /* Low */ + { + /* Set the signal down */ + ulGPIOData = PEEK32(g_i2cClkGPIODataReg); + ulGPIOData &= ~(1 << g_i2cClockGPIO); + POKE32(g_i2cClkGPIODataReg, ulGPIOData); + + /* Set direction as output */ + ulGPIODirection |= (1 << g_i2cClockGPIO); + POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection); + } +} + +/* + * This function set/reset the SDA GPIO pin + * + * Parameters: + * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + * + * Notes: + * When setting SCL to high, just set the GPIO as input where the pull up + * resistor will pull the signal up. Do not use software to pull up the + * signal because the i2c will fail when other device try to drive the + * signal due to SM50x will drive the signal to always high. + */ +void swI2CSDA(unsigned char value) +{ + unsigned long ulGPIOData; + unsigned long ulGPIODirection; + + ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg); + if (value) /* High */ + { + /* Set direction as input. This will automatically pull the signal up. */ + ulGPIODirection &= ~(1 << g_i2cDataGPIO); + POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection); + } + else /* Low */ + { + /* Set the signal down */ + ulGPIOData = PEEK32(g_i2cDataGPIODataReg); + ulGPIOData &= ~(1 << g_i2cDataGPIO); + POKE32(g_i2cDataGPIODataReg, ulGPIOData); + + /* Set direction as output */ + ulGPIODirection |= (1 << g_i2cDataGPIO); + POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection); + } +} + +/* + * This function read the data from the SDA GPIO pin + * + * Return Value: + * The SDA data bit sent by the Slave + */ +static unsigned char swI2CReadSDA(void) +{ + unsigned long ulGPIODirection; + unsigned long ulGPIOData; + + /* Make sure that the direction is input (High) */ + ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg); + if ((ulGPIODirection & (1 << g_i2cDataGPIO)) != (~(1 << g_i2cDataGPIO))) + { + ulGPIODirection &= ~(1 << g_i2cDataGPIO); + POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection); + } + + /* Now read the SDA line */ + ulGPIOData = PEEK32(g_i2cDataGPIODataReg); + if (ulGPIOData & (1 << g_i2cDataGPIO)) + return 1; + else + return 0; +} + +#pragma optimize( "", off ) + +/* + * This function sends ACK signal + */ +static void swI2CAck(void) +{ + return; /* Single byte read is ok without it. */ +} + +/* + * This function sends the start command to the slave device + */ +void swI2CStart(void) +{ + /* Start I2C */ + swI2CSDA(1); + swI2CSCL(1); + swI2CSDA(0); +} + +/* + * This function sends the stop command to the slave device + */ +void swI2CStop(void) +{ + /* Stop the I2C */ + swI2CSCL(1); + swI2CSDA(0); + swI2CSDA(1); +} + +/* + * This function writes one byte to the slave device + * + * Parameters: + * data - Data to be write to the slave device + * + * Return Value: + * 0 - Success + * -1 - Fail to write byte + */ +long swI2CWriteByte(unsigned char data) +{ + unsigned char value = data; + int i; + + /* Sending the data bit by bit */ + for (i=0; i<8; i++) + { + /* Set SCL to low */ + swI2CSCL(0); + + /* Send data bit */ + if ((value & 0x80) != 0) + swI2CSDA(1); + else + swI2CSDA(0); + + swI2CWait(); + + /* Toggle clk line to one */ + swI2CSCL(1); + swI2CWait(); + + /* Shift byte to be sent */ + value = value << 1; + } + + /* Set the SCL Low and SDA High (prepare to get input) */ + swI2CSCL(0); + swI2CSDA(1); + + /* Set the SCL High for ack */ + swI2CWait(); + swI2CSCL(1); + swI2CWait(); + + /* Read SDA, until SDA==0 */ + for(i=0; i<0xff; i++) + { + if (!swI2CReadSDA()) + break; + + swI2CSCL(0); + swI2CWait(); + swI2CSCL(1); + swI2CWait(); + } + + /* Set the SCL Low and SDA High */ + swI2CSCL(0); + swI2CSDA(1); + + if (i<0xff) + return 0; + else + return (-1); +} + +/* + * This function reads one byte from the slave device + * + * Parameters: + * ack - Flag to indicate either to send the acknowledge + * message to the slave device or not + * + * Return Value: + * One byte data read from the Slave device + */ +unsigned char swI2CReadByte(unsigned char ack) +{ + int i; + unsigned char data = 0; + + for(i=7; i>=0; i--) + { + /* Set the SCL to Low and SDA to High (Input) */ + swI2CSCL(0); + swI2CSDA(1); + swI2CWait(); + + /* Set the SCL High */ + swI2CSCL(1); + swI2CWait(); + + /* Read data bits from SDA */ + data |= (swI2CReadSDA() << i); + } + + if (ack) + swI2CAck(); + + /* Set the SCL Low and SDA High */ + swI2CSCL(0); + swI2CSDA(1); + + return data; +} +#pragma optimize( "", on ) + +/* + * This function initializes GPIO port for SW I2C communication. + * + * Parameters: + * i2cClkGPIO - The GPIO pin to be used as i2c SCL + * i2cDataGPIO - The GPIO pin to be used as i2c SDA + * + * Return Value: + * -1 - Fail to initialize the i2c + * 0 - Success + */ +long swI2CInit_SM750LE( + unsigned char i2cClkGPIO, + unsigned char i2cDataGPIO +) +{ + int i; + + /* Initialize the GPIO pin for the i2c Clock Register */ + g_i2cClkGPIODataReg = GPIO_DATA_SM750LE; + g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE; + + /* Initialize the Clock GPIO Offset */ + g_i2cClockGPIO = i2cClkGPIO; + + /* Initialize the GPIO pin for the i2c Data Register */ + g_i2cDataGPIODataReg = GPIO_DATA_SM750LE; + g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE; + + /* Initialize the Data GPIO Offset */ + g_i2cDataGPIO = i2cDataGPIO; + + /* Note that SM750LE don't have GPIO MUX and power is always on */ + + /* Clear the i2c lines. */ + for(i=0; i<9; i++) + swI2CStop(); + + return 0; +} + +/* + * This function initializes the i2c attributes and bus + * + * Parameters: + * i2cClkGPIO - The GPIO pin to be used as i2c SCL + * i2cDataGPIO - The GPIO pin to be used as i2c SDA + * + * Return Value: + * -1 - Fail to initialize the i2c + * 0 - Success + */ +long swI2CInit( + unsigned char i2cClkGPIO, + unsigned char i2cDataGPIO +) +{ + int i; + + /* Return 0 if the GPIO pins to be used is out of range. The range is only from [0..63] */ + if ((i2cClkGPIO > 31) || (i2cDataGPIO > 31)) + return (-1); + + if (getChipType() == SM750LE) + return( swI2CInit_SM750LE(i2cClkGPIO, i2cDataGPIO) ); + + /* Initialize the GPIO pin for the i2c Clock Register */ + g_i2cClkGPIOMuxReg = GPIO_MUX; + g_i2cClkGPIODataReg = GPIO_DATA; + g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION; + + /* Initialize the Clock GPIO Offset */ + g_i2cClockGPIO = i2cClkGPIO; + + /* Initialize the GPIO pin for the i2c Data Register */ + g_i2cDataGPIOMuxReg = GPIO_MUX; + g_i2cDataGPIODataReg = GPIO_DATA; + g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION; + + /* Initialize the Data GPIO Offset */ + g_i2cDataGPIO = i2cDataGPIO; + + /* Enable the GPIO pins for the i2c Clock and Data (GPIO MUX) */ + POKE32(g_i2cClkGPIOMuxReg, + PEEK32(g_i2cClkGPIOMuxReg) & ~(1 << g_i2cClockGPIO)); + POKE32(g_i2cDataGPIOMuxReg, + PEEK32(g_i2cDataGPIOMuxReg) & ~(1 << g_i2cDataGPIO)); + + /* Enable GPIO power */ + enableGPIO(1); + + /* Clear the i2c lines. */ + for(i=0; i<9; i++) + swI2CStop(); + + return 0; +} + +/* + * This function reads the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be read from + * registerIndex - Slave device's register to be read + * + * Return Value: + * Register value + */ +unsigned char swI2CReadReg( + unsigned char deviceAddress, + unsigned char registerIndex +) +{ + unsigned char data; + + /* Send the Start signal */ + swI2CStart(); + + /* Send the device address */ + swI2CWriteByte(deviceAddress); + + /* Send the register index */ + swI2CWriteByte(registerIndex); + + /* Get the bus again and get the data from the device read address */ + swI2CStart(); + swI2CWriteByte(deviceAddress + 1); + data = swI2CReadByte(1); + + /* Stop swI2C and release the bus */ + swI2CStop(); + + return data; +} + +/* + * This function writes a value to the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be written + * registerIndex - Slave device's register to be written + * data - Data to be written to the register + * + * Result: + * 0 - Success + * -1 - Fail + */ +long swI2CWriteReg( + unsigned char deviceAddress, + unsigned char registerIndex, + unsigned char data +) +{ + long returnValue = 0; + + /* Send the Start signal */ + swI2CStart(); + + /* Send the device address and read the data. All should return success + in order for the writing processed to be successful + */ + if ((swI2CWriteByte(deviceAddress) != 0) || + (swI2CWriteByte(registerIndex) != 0) || + (swI2CWriteByte(data) != 0)) + { + returnValue = -1; + } + + /* Stop i2c and release the bus */ + swI2CStop(); + + return returnValue; +} diff --git a/drivers/staging/sm750fb/ddk750_swi2c.h b/drivers/staging/sm750fb/ddk750_swi2c.h new file mode 100644 index 000000000000..ec5463b98ddf --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_swi2c.h @@ -0,0 +1,92 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* swi2c.h --- SM750/SM718 DDK +* This file contains the definitions for i2c using software +* implementation. +* +*******************************************************************/ +#ifndef _SWI2C_H_ +#define _SWI2C_H_ + +/* Default i2c CLK and Data GPIO. These are the default i2c pins */ +#define DEFAULT_I2C_SCL 30 +#define DEFAULT_I2C_SDA 31 + +/* + * This function initializes the i2c attributes and bus + * + * Parameters: + * i2cClkGPIO - The GPIO pin to be used as i2c SCL + * i2cDataGPIO - The GPIO pin to be used as i2c SDA + * + * Return Value: + * -1 - Fail to initialize the i2c + * 0 - Success + */ +long swI2CInit( + unsigned char i2cClkGPIO, + unsigned char i2cDataGPIO +); + +/* + * This function reads the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be read from + * registerIndex - Slave device's register to be read + * + * Return Value: + * Register value + */ +unsigned char swI2CReadReg( + unsigned char deviceAddress, + unsigned char registerIndex +); + +/* + * This function writes a value to the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be written + * registerIndex - Slave device's register to be written + * data - Data to be written to the register + * + * Result: + * 0 - Success + * -1 - Fail + */ +long swI2CWriteReg( + unsigned char deviceAddress, + unsigned char registerIndex, + unsigned char data +); + +/* + * These two functions are used to toggle the data on the SCL and SDA I2C lines. + * The used of these two functions are not recommended unless it is necessary. + */ + +/* + * This function set/reset the SCL GPIO pin + * + * Parameters: + * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + */ +void swI2CSCL(unsigned char value); + +/* + * This function set/reset the SDA GPIO pin + * + * Parameters: + * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + */ +void swI2CSDA(unsigned char value); + +#endif /* _SWI2C_H_ */ diff --git a/drivers/staging/sm750fb/modedb.h b/drivers/staging/sm750fb/modedb.h new file mode 100644 index 000000000000..c5275c6fffaf --- /dev/null +++ b/drivers/staging/sm750fb/modedb.h @@ -0,0 +1,221 @@ + +static const struct fb_videomode modedb2[] = { + { + /* 640x400 @ 70 Hz, 31.5 kHz hsync */ + NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, + 0, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 60 Hz, 31.5 kHz hsync */ + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, + 0, FB_VMODE_NONINTERLACED + }, { + /* 800x600 @ 56 Hz, 35.15 kHz hsync */ + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */ + NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8, + 0, FB_VMODE_INTERLACED + }, { + /* 640x400 @ 85 Hz, 37.86 kHz hsync */ + NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 72 Hz, 36.5 kHz hsync */ + NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 75 Hz, 37.50 kHz hsync */ + NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 800x600 @ 60 Hz, 37.8 kHz hsync */ + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 85 Hz, 43.27 kHz hsync */ + NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */ + NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, + 0, FB_VMODE_INTERLACED + }, { + /* 800x600 @ 72 Hz, 48.0 kHz hsync */ + NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */ + NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 100 Hz, 53.01 kHz hsync */ + NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 60 Hz, 53.5 kHz hsync */ + NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8, + 0, FB_VMODE_NONINTERLACED + }, { + /* 800x600 @ 85 Hz, 55.84 kHz hsync */ + NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */ + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x960-60 VESA */ + NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA + }, { + /* 1280x1024-60 VESA */ + NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA + }, { + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */ + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, + 0, FB_VMODE_INTERLACED + }, { + /* 800x600 @ 100 Hz, 64.02 kHz hsync */ + NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 76 Hz, 62.5 kHz hsync */ + NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 70 Hz, 62.4 kHz hsync */ + NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */ + NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1400x1050 @ 60Hz, 63.9 kHz hsync */ + NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/ + NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/ + NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 85 Hz, 70.24 kHz hsync */ + NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 78 Hz, 70.8 kHz hsync */ + NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */ + NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1600x1200 @ 60Hz, 75.00 kHz hsync */ + NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 84 Hz, 76.0 kHz hsync */ + NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */ + NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 100Hz, 80.21 kHz hsync */ + NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */ + NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */ + NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 100 Hz, 89.62 kHz hsync */ + NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */ + NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */ + NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */ + NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */ + NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1800x1440 @ 64Hz, 96.15 kHz hsync */ + NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1800x1440 @ 70Hz, 104.52 kHz hsync */ + NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 512x384 @ 78 Hz, 31.50 kHz hsync */ + NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 512x384 @ 85 Hz, 34.38 kHz hsync */ + NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */ + NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1, + 0, FB_VMODE_DOUBLE + }, { + /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */ + NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1, + 0, FB_VMODE_DOUBLE + }, { + /* 320x240 @ 72 Hz, 36.5 kHz hsync */ + NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2, + 0, FB_VMODE_DOUBLE + }, { + /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */ + NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1, + 0, FB_VMODE_DOUBLE + }, { + /* 400x300 @ 60 Hz, 37.8 kHz hsync */ + NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2, + 0, FB_VMODE_DOUBLE + }, { + /* 400x300 @ 72 Hz, 48.0 kHz hsync */ + NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3, + 0, FB_VMODE_DOUBLE + }, { + /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */ + NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1, + 0, FB_VMODE_DOUBLE + }, { + /* 480x300 @ 60 Hz, 37.8 kHz hsync */ + NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2, + 0, FB_VMODE_DOUBLE + }, { + /* 480x300 @ 63 Hz, 39.6 kHz hsync */ + NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2, + 0, FB_VMODE_DOUBLE + }, { + /* 480x300 @ 72 Hz, 48.0 kHz hsync */ + NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, + 0, FB_VMODE_DOUBLE + }, +}; +static const int nmodedb2 = sizeof(modedb2); diff --git a/drivers/staging/sm750fb/readme b/drivers/staging/sm750fb/readme new file mode 100644 index 000000000000..ab9af791653d --- /dev/null +++ b/drivers/staging/sm750fb/readme @@ -0,0 +1,38 @@ +Introduction: + SM750 of Silicon MOtion is pci express display controller device. + The SM750 embedded graphics features include: + - dual display + - 2D acceleration + - 16MB integrated video memory + +About the kernel module paramter of driver: + + Use 1280,8bpp index color and 60 hz mode: + insmod ./sm750fb.ko g_option="1280x1024-8@60" + + Disable MTRR,Disable 2d acceleration,Disable hardware cursor, + and use a 800x600 mode : + insmod ./sm750fb.ko g_option="noaccel:nomtrr:nohwc:800x600" + + dual frame buffer for driver with "dual" parameter + insmod ./sm750fb.ko g_option="dual,800x600:1024x768" + it will create fb0 and fb1 (or fb1,fb2 if fb0 already exist) under /dev + and user can use con2fb to link fbX and ttyX + + Notes: + 1) if you build the driver with built-in method, the paramter + you edited in the grub config file will be also the + same format as above modular method,but additionaly add + "video=sm750fb:" + ahead of parameters,so,it looks like: + video=sm750fb:noaccel,1280x1024@60,otherparam,etc... + it equal to modular method with below command: + insmod ./sm750fb.ko g_option="noaccel:1280x1024@60:otherparm:etc..." + + 2) if you put 800x600 into the paramter without bpp and + refresh rate, kernel driver will defaulty use 16bpp and 60hz + +Important: + if you have vesafb enabled in your config then /dev/fb0 will be created by vesafb + and this driver will use fb1, fb2. In that case, you need to configure your X-server + to use fb1. Another simple althernative is to disable vesafb from your config. diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c new file mode 100644 index 000000000000..520c69e3ab74 --- /dev/null +++ b/drivers/staging/sm750fb/sm750.c @@ -0,0 +1,1451 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MTRR +#include +#endif +#include +#include "sm750.h" +#include "sm750_hw.h" +#include "sm750_accel.h" +#include "sm750_cursor.h" + +#include "modedb.h" + +int smi_indent = 0; + + +/* +#ifdef __BIG_ENDIAN +ssize_t lynxfb_ops_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos); +ssize_t lynxfb_ops_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos); +#endif + */ + +typedef void (*PROC_SPEC_SETUP)(struct lynx_share*,char *); +typedef int (*PROC_SPEC_MAP)(struct lynx_share*,struct pci_dev*); +typedef int (*PROC_SPEC_INITHW)(struct lynx_share*,struct pci_dev*); + + +/* common var for all device */ +static int g_hwcursor = 1; +static int g_noaccel = 0; +#ifdef CONFIG_MTRR +static int g_nomtrr = 0; +#endif +static const char * g_fbmode[] = {NULL,NULL}; +static const char * g_def_fbmode = "800x600-16@60"; +static char * g_settings = NULL; +static int g_dualview = 0; +#ifdef MODULE +static char * g_option = NULL; +#endif + +/* if not use spin_lock,system will die if user load driver + * and immediatly unload driver frequently (dual)*/ +static inline void myspin_lock(spinlock_t * sl){ + struct lynx_share * share; + share = container_of(sl,struct lynx_share,slock); + if(share->dual){ + spin_lock(sl); + } +} + +static inline void myspin_unlock(spinlock_t * sl){ + struct lynx_share * share; + share = container_of(sl,struct lynx_share,slock); + if(share->dual){ + spin_unlock(sl); + } +} +static const struct fb_videomode lynx750_ext[] = { + /* 1024x600-60 VESA [1.71:1] */ + {NULL, 60, 1024, 600, 20423, 144, 40, 18, 1, 104, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1024x600-70 VESA */ + {NULL, 70, 1024, 600, 17211, 152, 48, 21, 1, 104, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1024x600-75 VESA */ + {NULL, 75, 1024, 600, 15822, 160, 56, 23, 1, 104, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1024x600-85 VESA */ + {NULL, 85, 1024, 600, 13730, 168, 56, 26, 1, 112, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 720x480 */ + {NULL, 60, 720, 480, 37427, 88, 16, 13, 1, 72, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1280x720 [1.78:1] */ + {NULL, 60, 1280, 720, 13426, 162, 86, 22, 1, 136, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED}, + + /* 1280x768@60 */ + {NULL,60,1280,768,12579,192,64,20,3,128,7, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED}, + + {NULL,60,1360,768,11804,208,64,23,1,144,3, + FB_SYNC_HOR_HIGH_ACT|FB_VMODE_NONINTERLACED}, + + /* 1360 x 768 [1.77083:1] */ + {NULL, 60, 1360, 768, 11804, 208, 64, 23, 1, 144, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1368 x 768 [1.78:1] */ + {NULL, 60, 1368, 768, 11647, 216, 72, 23, 1, 144, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1440 x 900 [16:10] */ + {NULL, 60, 1440, 900, 9392, 232, 80, 28, 1, 152, 3, + FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED}, + + /* 1440x960 [15:10] */ + {NULL, 60, 1440, 960, 8733, 240, 88, 30, 1, 152, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1920x1080 [16:9] */ + {NULL, 60, 1920, 1080, 6734, 148, 88, 41, 1, 44, 3, + FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED}, +}; + + + + +/* no hardware cursor supported under version 2.6.10, kernel bug */ +static int lynxfb_ops_cursor(struct fb_info* info,struct fb_cursor* fbcursor) +{ + struct lynxfb_par * par; + struct lynxfb_crtc * crtc; + struct lynx_cursor * cursor; + + par = info->par; + crtc = &par->crtc; + cursor = &crtc->cursor; + + if(fbcursor->image.width > cursor->maxW || + fbcursor->image.height > cursor->maxH || + fbcursor->image.depth > 1){ + return -ENXIO; + } + + cursor->disable(cursor); + if(fbcursor->set & FB_CUR_SETSIZE){ + cursor->setSize(cursor,fbcursor->image.width,fbcursor->image.height); + } + + if(fbcursor->set & FB_CUR_SETPOS){ + cursor->setPos(cursor,fbcursor->image.dx - info->var.xoffset, + fbcursor->image.dy - info->var.yoffset); + } + + if(fbcursor->set & FB_CUR_SETCMAP){ + /* get the 16bit color of kernel means */ + u16 fg,bg; + fg = ((info->cmap.red[fbcursor->image.fg_color] & 0xf800))| + ((info->cmap.green[fbcursor->image.fg_color] & 0xfc00) >> 5)| + ((info->cmap.blue[fbcursor->image.fg_color] & 0xf800) >> 11); + + bg = ((info->cmap.red[fbcursor->image.bg_color] & 0xf800))| + ((info->cmap.green[fbcursor->image.bg_color] & 0xfc00) >> 5)| + ((info->cmap.blue[fbcursor->image.bg_color] & 0xf800) >> 11); + + cursor->setColor(cursor,fg,bg); + } + + + if(fbcursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) + { + cursor->setData(cursor, + fbcursor->rop, + fbcursor->image.data, + fbcursor->mask); + } + + if(fbcursor->enable){ + cursor->enable(cursor); + } + + return 0; +} + +static void lynxfb_ops_fillrect(struct fb_info* info,const struct fb_fillrect* region) +{ + struct lynxfb_par * par; + struct lynx_share * share; + unsigned int base,pitch,Bpp,rop; + u32 color; + + if(info->state != FBINFO_STATE_RUNNING){ + return; + } + + par = info->par; + share = par->share; + + /* each time 2d function begin to work,below three variable always need + * be set, seems we can put them together in some place */ + base = par->crtc.oScreen; + pitch = info->fix.line_length; + Bpp = info->var.bits_per_pixel >> 3; + + color = (Bpp == 1)?region->color:((u32*)info->pseudo_palette)[region->color]; + rop = ( region->rop != ROP_COPY ) ? HW_ROP2_XOR:HW_ROP2_COPY; + + myspin_lock(&share->slock); + share->accel.de_fillrect(&share->accel, + base,pitch,Bpp, + region->dx,region->dy, + region->width,region->height, + color,rop); + myspin_unlock(&share->slock); +} + +static void lynxfb_ops_copyarea(struct fb_info * info,const struct fb_copyarea * region) +{ + struct lynxfb_par * par; + struct lynx_share * share; + unsigned int base,pitch,Bpp; + + par = info->par; + share = par->share; + + /* each time 2d function begin to work,below three variable always need + * be set, seems we can put them together in some place */ + base = par->crtc.oScreen; + pitch = info->fix.line_length; + Bpp = info->var.bits_per_pixel >> 3; + + myspin_lock(&share->slock); + share->accel.de_copyarea(&share->accel, + base,pitch,region->sx,region->sy, + base,pitch,Bpp,region->dx,region->dy, + region->width,region->height,HW_ROP2_COPY); + myspin_unlock(&share->slock); +} + +static void lynxfb_ops_imageblit(struct fb_info*info,const struct fb_image* image) +{ + unsigned int base,pitch,Bpp; + unsigned int fgcol,bgcol; + struct lynxfb_par * par; + struct lynx_share * share; + + par = info->par; + share = par->share; + /* each time 2d function begin to work,below three variable always need + * be set, seems we can put them together in some place */ + base = par->crtc.oScreen; + pitch = info->fix.line_length; + Bpp = info->var.bits_per_pixel >> 3; + + if(image->depth == 1){ + if(info->fix.visual == FB_VISUAL_TRUECOLOR || + info->fix.visual == FB_VISUAL_DIRECTCOLOR) + { + fgcol = ((u32*)info->pseudo_palette)[image->fg_color]; + bgcol = ((u32*)info->pseudo_palette)[image->bg_color]; + } + else + { + fgcol = image->fg_color; + bgcol = image->bg_color; + } + goto _do_work; + } + return; +_do_work: + myspin_lock(&share->slock); + share->accel.de_imageblit(&share->accel, + image->data,image->width>>3,0, + base,pitch,Bpp, + image->dx,image->dy, + image->width,image->height, + fgcol,bgcol,HW_ROP2_COPY); + myspin_unlock(&share->slock); +} + +static int lynxfb_ops_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + struct lynxfb_par * par; + struct lynxfb_crtc * crtc; + int ret; + + + if(!info) + return -EINVAL; + + ret = 0; + par = info->par; + crtc = &par->crtc; + ret = crtc->proc_panDisplay(crtc, var, info); + + return ret; +} + + + + +#ifdef CONFIG_PM +static int lynxfb_suspend(struct pci_dev * pdev,pm_message_t mesg) +{ + struct fb_info * info; + struct lynx_share * share; + int ret; + + + if(mesg.event == pdev->dev.power.power_state.event) + return 0; + + ret = 0; + share = pci_get_drvdata(pdev); + switch (mesg.event) { + case PM_EVENT_FREEZE: + case PM_EVENT_PRETHAW: + pdev->dev.power.power_state = mesg; + return 0; + } + + console_lock(); + if (mesg.event & PM_EVENT_SLEEP) { + info = share->fbinfo[0]; + if(info) + fb_set_suspend(info, 1);/* 1 means do suspend*/ + + info = share->fbinfo[1]; + if(info) + fb_set_suspend(info, 1);/* 1 means do suspend*/ + + ret = pci_save_state(pdev); + if(ret){ + pr_err("error:%d occured in pci_save_state\n",ret); + return ret; + } + + /* set chip to sleep mode */ + if(share->suspend) + (*share->suspend)(share); + + pci_disable_device(pdev); + ret = pci_set_power_state(pdev,pci_choose_state(pdev,mesg)); + if(ret){ + pr_err("error:%d occured in pci_set_power_state\n",ret); + return ret; + } + } + + pdev->dev.power.power_state = mesg; + console_unlock(); + return ret; +} + +static int lynxfb_ops_set_par(struct fb_info * info) +{ + struct lynxfb_par * par; + struct lynx_share * share; + struct lynxfb_crtc * crtc; + struct lynxfb_output * output; + struct fb_var_screeninfo * var; + struct fb_fix_screeninfo * fix; + int ret; + unsigned int line_length; + + + if(!info) + return -EINVAL; + + ret = 0; + par = info->par; + share = par->share; + crtc = &par->crtc; + output = &par->output; + var = &info->var; + fix = &info->fix; + + /* fix structur is not so FIX ... */ + line_length = var->xres_virtual * var->bits_per_pixel / 8; + line_length = PADDING(crtc->line_pad,line_length); + fix->line_length = line_length; + pr_err("fix->line_length = %d\n",fix->line_length); + + /* var->red,green,blue,transp are need to be set by driver + * and these data should be set before setcolreg routine + * */ + + switch(var->bits_per_pixel){ + case 8: + fix->visual = FB_VISUAL_PSEUDOCOLOR; + var->red.offset = 0; + var->red.length = 8; + var->green.offset = 0; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + var->transp.length = 0; + var->transp.offset = 0; + break; + case 16: + var->red.offset = 11; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 6; + var->blue.offset = 0; + var->blue.length = 5; + var->transp.length = 0; + var->transp.offset = 0; + fix->visual = FB_VISUAL_TRUECOLOR; + break; + case 24: + case 32: + var->red.offset = 16; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 0 ; + var->blue.length = 8; + fix->visual = FB_VISUAL_TRUECOLOR; + break; + default: + ret = -EINVAL; + break; + } + var->height = var->width = -1; + var->accel_flags = 0;/*FB_ACCELF_TEXT;*/ + + if(ret){ + pr_err("pixel bpp format not satisfied\n."); + return ret; + } + ret = crtc->proc_setMode(crtc,var,fix); + if(!ret) + ret = output->proc_setMode(output,var,fix); + return ret; +} +static inline unsigned int chan_to_field(unsigned int chan,struct fb_bitfield * bf) +{ + chan &= 0xffff; + chan >>= 16 - bf->length; + return chan << bf->offset; +} + + +static int lynxfb_resume(struct pci_dev* pdev) +{ + struct fb_info * info; + struct lynx_share * share; + + struct lynxfb_par * par; + struct lynxfb_crtc * crtc; + struct lynx_cursor * cursor; + + int ret; + + + ret = 0; + share = pci_get_drvdata(pdev); + + console_lock(); + + if((ret = pci_set_power_state(pdev, PCI_D0)) != 0){ + pr_err("error:%d occured in pci_set_power_state\n",ret); + return ret; + } + + + if(pdev->dev.power.power_state.event != PM_EVENT_FREEZE){ + pci_restore_state(pdev); + if ((ret = pci_enable_device(pdev)) != 0){ + pr_err("error:%d occured in pci_enable_device\n",ret); + return ret; + } + pci_set_master(pdev); + } + if(share->resume) + (*share->resume)(share); + + hw_sm750_inithw(share,pdev); + + + info = share->fbinfo[0]; + + if(info){ + par = info->par; + crtc = &par->crtc; + cursor = &crtc->cursor; + memset(cursor->vstart, 0x0, cursor->size); + memset(crtc->vScreen,0x0,crtc->vidmem_size); + lynxfb_ops_set_par(info); + fb_set_suspend(info, 0); + } + + info = share->fbinfo[1]; + + if(info){ + par = info->par; + crtc = &par->crtc; + cursor = &crtc->cursor; + memset(cursor->vstart, 0x0, cursor->size); + memset(crtc->vScreen,0x0,crtc->vidmem_size); + lynxfb_ops_set_par(info); + fb_set_suspend(info, 0); + } + + + console_unlock(); + return ret; +} +#endif + +static int lynxfb_ops_mmap(struct fb_info * info, struct vm_area_struct * vma) +{ + unsigned long off; + unsigned long start; + u32 len; + struct file *file; + + file = vma->vm_file; + + if (!info) + return -ENODEV; + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) + return -EINVAL; + off = vma->vm_pgoff << PAGE_SHIFT; + printk("lynxfb mmap pgoff: %x\n", vma->vm_pgoff); + printk("lynxfb mmap off 1: %x\n", off); + + /* frame buffer memory */ + start = info->fix.smem_start; + len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); + + printk("lynxfb mmap start 1: %x\n", start); + printk("lynxfb mmap len 1: %x\n", len); + + if (off >= len) { + /* memory mapped io */ + off -= len; + printk("lynxfb mmap off 2: %x\n", off); + if (info->var.accel_flags) { + printk("lynxfb mmap accel flags true"); + return -EINVAL; + } + start = info->fix.mmio_start; + len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); + + printk("lynxfb mmap start 2: %x\n", start); + printk("lynxfb mmap len 2: %x\n", len); + } + start &= PAGE_MASK; + printk("lynxfb mmap start 3: %x\n", start); + printk("lynxfb mmap vm start: %x\n", vma->vm_start); + printk("lynxfb mmap vm end: %x\n", vma->vm_end); + printk("lynxfb mmap len: %x\n", len); + printk("lynxfb mmap off: %x\n", off); + if ((vma->vm_end - vma->vm_start + off) > len) + { + return -EINVAL; + } + off += start; + printk("lynxfb mmap off 3: %x\n", off); + vma->vm_pgoff = off >> PAGE_SHIFT; + /* This is an IO map - tell maydump to skip this VMA */ + vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + fb_pgprotect(file, vma, off); + printk("lynxfb mmap off 4: %x\n", off); + printk("lynxfb mmap pgprot: %x\n", vma->vm_page_prot); + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) + return -EAGAIN; + return 0; +} + +static int lynxfb_ops_check_var(struct fb_var_screeninfo* var,struct fb_info* info) +{ + struct lynxfb_par * par; + struct lynxfb_crtc * crtc; + struct lynxfb_output * output; + struct lynx_share * share; + int ret; + resource_size_t request; + + + par = info->par; + crtc = &par->crtc; + output = &par->output; + share = par->share; + ret = 0; + + pr_debug("check var:%dx%d-%d\n", + var->xres, + var->yres, + var->bits_per_pixel); + + + switch(var->bits_per_pixel){ + case 8: + case 16: + case 24: /* support 24 bpp for only lynx712/722/720 */ + case 32: + break; + default: + pr_err("bpp %d not supported\n",var->bits_per_pixel); + ret = -EINVAL; + goto exit; + } + + switch(var->bits_per_pixel){ + case 8: + info->fix.visual = FB_VISUAL_PSEUDOCOLOR; + var->red.offset = 0; + var->red.length = 8; + var->green.offset = 0; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + var->transp.length = 0; + var->transp.offset = 0; + break; + case 16: + var->red.offset = 11; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 6; + var->blue.offset = 0; + var->blue.length = 5; + var->transp.length = 0; + var->transp.offset = 0; + info->fix.visual = FB_VISUAL_TRUECOLOR; + break; + case 24: + case 32: + var->red.offset = 16; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 0 ; + var->blue.length = 8; + info->fix.visual = FB_VISUAL_TRUECOLOR; + break; + default: + ret = -EINVAL; + break; + } + var->height = var->width = -1; + var->accel_flags = 0;/*FB_ACCELF_TEXT;*/ + + /* check if current fb's video memory big enought to hold the onscreen */ + request = var->xres_virtual * (var->bits_per_pixel >> 3); + /* defaulty crtc->channel go with par->index */ + + request = PADDING(crtc->line_pad,request); + request = request * var->yres_virtual; + if(crtc->vidmem_size < request){ + pr_err("not enough video memory for mode\n"); + return -ENOMEM; + } + + ret = output->proc_checkMode(output,var); + if(!ret) + ret = crtc->proc_checkMode(crtc,var); +exit: + return ret; +} + + +static int lynxfb_ops_setcolreg(unsigned regno,unsigned red, + unsigned green,unsigned blue, + unsigned transp,struct fb_info * info) +{ + struct lynxfb_par * par; + struct lynxfb_crtc * crtc; + struct fb_var_screeninfo * var; + int ret; + + par = info->par; + crtc = &par->crtc; + var = &info->var; + ret = 0; + + //pr_debug("regno=%d,red=%d,green=%d,blue=%d\n",regno,red,green,blue); + if(regno > 256){ + pr_err("regno = %d\n",regno); + return -EINVAL; + } + + if(info->var.grayscale) + red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; + + if(var->bits_per_pixel == 8 && info->fix.visual == FB_VISUAL_PSEUDOCOLOR) + { + red >>= 8; + green >>= 8; + blue >>= 8; + ret = crtc->proc_setColReg(crtc,regno,red,green,blue); + goto exit; + } + + + if(info->fix.visual == FB_VISUAL_TRUECOLOR && regno < 256 ) + { + u32 val; + if(var->bits_per_pixel == 16 || + var->bits_per_pixel == 32 || + var->bits_per_pixel == 24) + { + val = chan_to_field(red,&var->red); + val |= chan_to_field(green,&var->green); + val |= chan_to_field(blue,&var->blue); + par->pseudo_palette[regno] = val; + goto exit; + } + } + + ret = -EINVAL; + +exit: + return ret; +} + +static int lynxfb_ops_blank(int blank,struct fb_info* info) +{ + struct lynxfb_par * par; + struct lynxfb_output * output; + + pr_debug("blank = %d.\n",blank); + par = info->par; + output = &par->output; + return output->proc_setBLANK(output,blank); +} + +static int sm750fb_set_drv(struct lynxfb_par * par) +{ + int ret; + struct lynx_share * share; + struct sm750_share * spec_share; + struct lynxfb_output * output; + struct lynxfb_crtc * crtc; + + ret = 0; + + share = par->share; + spec_share = container_of(share,struct sm750_share,share); + output = &par->output; + crtc = &par->crtc; + + crtc->vidmem_size = (share->dual)?share->vidmem_size>>1:share->vidmem_size; + /* setup crtc and output member */ + spec_share->hwCursor = g_hwcursor; + + crtc->proc_setMode = hw_sm750_crtc_setMode; + crtc->proc_checkMode = hw_sm750_crtc_checkMode; + crtc->proc_setColReg = hw_sm750_setColReg; + crtc->proc_panDisplay = hw_sm750_pan_display; + crtc->clear = hw_sm750_crtc_clear; + crtc->line_pad = 16; + //crtc->xpanstep = crtc->ypanstep = crtc->ywrapstep = 0; + crtc->xpanstep = 8; + crtc->ypanstep = 1; + crtc->ywrapstep = 0; + + output->proc_setMode = hw_sm750_output_setMode; + output->proc_checkMode = hw_sm750_output_checkMode; + + output->proc_setBLANK = (share->revid == SM750LE_REVISION_ID)?hw_sm750le_setBLANK:hw_sm750_setBLANK; + output->clear = hw_sm750_output_clear; + /* chip specific phase */ + share->accel.de_wait = (share->revid == SM750LE_REVISION_ID)?hw_sm750le_deWait: hw_sm750_deWait; + switch (spec_share->state.dataflow) + { + case sm750_simul_pri: + output->paths = sm750_pnc; + crtc->channel = sm750_primary; + crtc->oScreen = 0; + crtc->vScreen = share->pvMem; + pr_info("use simul primary mode\n"); + break; + case sm750_simul_sec: + output->paths = sm750_pnc; + crtc->channel = sm750_secondary; + crtc->oScreen = 0; + crtc->vScreen = share->pvMem; + break; + case sm750_dual_normal: + if(par->index == 0){ + output->paths = sm750_panel; + crtc->channel = sm750_primary; + crtc->oScreen = 0; + crtc->vScreen = share->pvMem; + }else{ + output->paths = sm750_crt; + crtc->channel = sm750_secondary; + /* not consider of padding stuffs for oScreen,need fix*/ + crtc->oScreen = (share->vidmem_size >> 1); + crtc->vScreen = share->pvMem + crtc->oScreen; + } + break; + case sm750_dual_swap: + if(par->index == 0){ + output->paths = sm750_panel; + crtc->channel = sm750_secondary; + crtc->oScreen = 0; + crtc->vScreen = share->pvMem; + }else{ + output->paths = sm750_crt; + crtc->channel = sm750_primary; + /* not consider of padding stuffs for oScreen,need fix*/ + crtc->oScreen = (share->vidmem_size >> 1); + crtc->vScreen = share->pvMem + crtc->oScreen; + } + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static struct fb_ops lynxfb_ops={ + .owner = THIS_MODULE, + .fb_check_var = lynxfb_ops_check_var, + .fb_set_par = lynxfb_ops_set_par, + .fb_setcolreg = lynxfb_ops_setcolreg, + .fb_blank = lynxfb_ops_blank, + /*.fb_mmap = lynxfb_ops_mmap,*/ + /* will be hooked by hardware */ + .fb_fillrect = cfb_fillrect, + .fb_imageblit = cfb_imageblit, + .fb_copyarea = cfb_copyarea, + /* cursor */ + .fb_cursor = lynxfb_ops_cursor, +}; + + +static int lynxfb_set_fbinfo(struct fb_info* info,int index) +{ + int i; + struct lynxfb_par * par; + struct lynx_share * share; + struct lynxfb_crtc * crtc; + struct lynxfb_output * output; + struct fb_var_screeninfo * var; + struct fb_fix_screeninfo * fix; + + const struct fb_videomode * pdb[] = { + lynx750_ext, NULL,vesa_modes, + }; + int cdb[] = {ARRAY_SIZE(lynx750_ext),0,VESA_MODEDB_SIZE}; + static const char * mdb_desc[] ={ + "driver prepared modes", + "kernel prepared default modedb", + "kernel HELPERS prepared vesa_modes", + }; + + + static const char * fixId[2]= + { + "sm750_fb1","sm750_fb2", + }; + + int ret,line_length; + + ret = 0; + par = (struct lynxfb_par *)info->par; + share = par->share; + crtc = &par->crtc; + output = &par->output; + var = &info->var; + fix = &info->fix; + + /* set index */ + par->index = index; + output->channel = &crtc->channel; + sm750fb_set_drv(par); + lynxfb_ops.fb_pan_display = lynxfb_ops_pan_display; + + + /* set current cursor variable and proc pointer, + * must be set after crtc member initialized */ + crtc->cursor.offset = crtc->oScreen + crtc->vidmem_size - 1024; + crtc->cursor.mmio = share->pvReg + 0x800f0 + (int)crtc->channel * 0x140; + + pr_info("crtc->cursor.mmio = %p\n",crtc->cursor.mmio); + crtc->cursor.maxH = crtc->cursor.maxW = 64; + crtc->cursor.size = crtc->cursor.maxH*crtc->cursor.maxW*2/8; + crtc->cursor.disable = hw_cursor_disable; + crtc->cursor.enable = hw_cursor_enable; + crtc->cursor.setColor = hw_cursor_setColor; + crtc->cursor.setPos = hw_cursor_setPos; + crtc->cursor.setSize = hw_cursor_setSize; + crtc->cursor.setData = hw_cursor_setData; + crtc->cursor.vstart = share->pvMem + crtc->cursor.offset; + + + crtc->cursor.share = share; + memset(crtc->cursor.vstart, 0, crtc->cursor.size); + if(!g_hwcursor){ + lynxfb_ops.fb_cursor = NULL; + crtc->cursor.disable(&crtc->cursor); + } + + + /* set info->fbops, must be set before fb_find_mode */ + if(!share->accel_off){ + /* use 2d acceleration */ + lynxfb_ops.fb_fillrect = lynxfb_ops_fillrect; + lynxfb_ops.fb_copyarea = lynxfb_ops_copyarea; + lynxfb_ops.fb_imageblit = lynxfb_ops_imageblit; + } + info->fbops = &lynxfb_ops; + + if(!g_fbmode[index]){ + g_fbmode[index] = g_def_fbmode; + if(index) + g_fbmode[index] = g_fbmode[0]; + } + + + for(i=0;i<3;i++){ + + ret = fb_find_mode(var,info,g_fbmode[index], + pdb[i],cdb[i],NULL,8); + + if(ret == 1){ + pr_info("success! use specified mode:%s in %s\n", + g_fbmode[index], + mdb_desc[i]); + break; + }else if(ret == 2){ + pr_warn("use specified mode:%s in %s,with an ignored refresh rate\n", + g_fbmode[index], + mdb_desc[i]); + break; + }else if(ret == 3){ + pr_warn("wanna use default mode\n"); +// break; + }else if(ret == 4){ + pr_warn("fall back to any valid mode\n"); + }else{ + pr_warn("ret = %d,fb_find_mode failed,with %s\n",ret,mdb_desc[i]); + } + } + + /* some member of info->var had been set by fb_find_mode */ + + pr_info("Member of info->var is :\n\ + xres=%d\n\ + yres=%d\n\ + xres_virtual=%d\n\ + yres_virtual=%d\n\ + xoffset=%d\n\ + yoffset=%d\n\ + bits_per_pixel=%d\n \ + ...\n",var->xres,var->yres,var->xres_virtual,var->yres_virtual, + var->xoffset,var->yoffset,var->bits_per_pixel); + + /* set par */ + par->info = info; + + /* set info */ + line_length = PADDING(crtc->line_pad, + (var->xres_virtual * var->bits_per_pixel/8)); + + info->pseudo_palette = &par->pseudo_palette[0]; + info->screen_base = crtc->vScreen; + pr_debug("screen_base vaddr = %p\n",info->screen_base); + info->screen_size = line_length * var->yres_virtual; + info->flags = FBINFO_FLAG_DEFAULT|0; + + /* set info->fix */ + fix->type = FB_TYPE_PACKED_PIXELS; + fix->type_aux = 0; + fix->xpanstep = crtc->xpanstep; + fix->ypanstep = crtc->ypanstep; + fix->ywrapstep = crtc->ywrapstep; + fix->accel = FB_ACCEL_SMI; + + strlcpy(fix->id,fixId[index],sizeof(fix->id)); + + + fix->smem_start = crtc->oScreen + share->vidmem_start; + pr_info("fix->smem_start = %lx\n",fix->smem_start); + /* according to mmap experiment from user space application, + * fix->mmio_len should not larger than virtual size + * (xres_virtual x yres_virtual x ByPP) + * Below line maybe buggy when user mmap fb dev node and write + * data into the bound over virtual size + * */ + fix->smem_len = crtc->vidmem_size; + pr_info("fix->smem_len = %x\n",fix->smem_len); + info->screen_size = fix->smem_len; + fix->line_length = line_length; + fix->mmio_start = share->vidreg_start; + pr_info("fix->mmio_start = %lx\n",fix->mmio_start); + fix->mmio_len = share->vidreg_size; + pr_info("fix->mmio_len = %x\n",fix->mmio_len); + switch(var->bits_per_pixel) + { + case 8: + fix->visual = FB_VISUAL_PSEUDOCOLOR; + break; + case 16: + case 32: + fix->visual = FB_VISUAL_TRUECOLOR; + break; + } + + /* set var */ + var->activate = FB_ACTIVATE_NOW; + var->accel_flags = 0; + var->vmode = FB_VMODE_NONINTERLACED; + + pr_debug("#1 show info->cmap : \nstart=%d,len=%d,red=%p,green=%p,blue=%p,transp=%p\n", + info->cmap.start,info->cmap.len, + info->cmap.red,info->cmap.green,info->cmap.blue, + info->cmap.transp); + + if((ret = fb_alloc_cmap(&info->cmap,256,0)) < 0){ + pr_err("Could not allcate memory for cmap.\n"); + goto exit; + } + + pr_debug("#2 show info->cmap : \nstart=%d,len=%d,red=%p,green=%p,blue=%p,transp=%p\n", + info->cmap.start,info->cmap.len, + info->cmap.red,info->cmap.green,info->cmap.blue, + info->cmap.transp); + +exit: + lynxfb_ops_check_var(var,info); +// lynxfb_ops_set_par(info); + return ret; +} + +/* chip specific g_option configuration routine */ +static void sm750fb_setup(struct lynx_share * share,char * src) +{ + struct sm750_share * spec_share; + char * opt; +#ifdef CAP_EXPENSION + char * exp_res; +#endif + int swap; + + + spec_share = container_of(share,struct sm750_share,share); +#ifdef CAP_EXPENSIION + exp_res = NULL; +#endif + swap = 0; + + spec_share->state.initParm.chip_clk = 0; + spec_share->state.initParm.mem_clk = 0; + spec_share->state.initParm.master_clk = 0; + spec_share->state.initParm.powerMode = 0; + spec_share->state.initParm.setAllEngOff = 0; + spec_share->state.initParm.resetMemory = 1; + + /*defaultly turn g_hwcursor on for both view */ + g_hwcursor = 3; + + if(!src || !*src){ + pr_warn("no specific g_option.\n"); + goto NO_PARAM; + } + + while((opt = strsep(&src,":")) != NULL && *opt != NULL){ + pr_err("opt=%s\n",opt); + pr_err("src=%s\n",src); + + if(!strncmp(opt,"swap",strlen("swap"))) + swap = 1; + else if(!strncmp(opt,"nocrt",strlen("nocrt"))) + spec_share->state.nocrt = 1; + else if(!strncmp(opt,"36bit",strlen("36bit"))) + spec_share->state.pnltype = sm750_doubleTFT; + else if(!strncmp(opt,"18bit",strlen("18bit"))) + spec_share->state.pnltype = sm750_dualTFT; + else if(!strncmp(opt,"24bit",strlen("24bit"))) + spec_share->state.pnltype = sm750_24TFT; +#ifdef CAP_EXPANSION + else if(!strncmp(opt,"exp:",strlen("exp:"))) + exp_res = opt + strlen("exp:"); +#endif + else if(!strncmp(opt,"nohwc0",strlen("nohwc0"))) + g_hwcursor &= ~0x1; + else if(!strncmp(opt,"nohwc1",strlen("nohwc1"))) + g_hwcursor &= ~0x2; + else if(!strncmp(opt,"nohwc",strlen("nohwc"))) + g_hwcursor = 0; + else + { + if(!g_fbmode[0]){ + g_fbmode[0] = opt; + pr_info("find fbmode0 : %s\n",g_fbmode[0]); + }else if(!g_fbmode[1]){ + g_fbmode[1] = opt; + pr_info("find fbmode1 : %s\n",g_fbmode[1]); + }else{ + pr_warn("How many view you wann set?\n"); + } + } + } +#ifdef CAP_EXPANSION + if(getExpRes(exp_res,&spec_share->state.xLCD,&spec_share->state.yLCD)) + { + /* seems exp_res is not valid*/ + spec_share->state.xLCD = spec_share->state.yLCD = 0; + } +#endif + +NO_PARAM: + if(share->revid != SM750LE_REVISION_ID){ + if(share->dual) + { + if(swap) + spec_share->state.dataflow = sm750_dual_swap; + else + spec_share->state.dataflow = sm750_dual_normal; + }else{ + if(swap) + spec_share->state.dataflow = sm750_simul_sec; + else + spec_share->state.dataflow = sm750_simul_pri; + } + }else{ + /* SM750LE only have one crt channel */ + spec_share->state.dataflow = sm750_simul_sec; + /* sm750le do not have complex attributes*/ + spec_share->state.nocrt = 0; + } +} + +static int lynxfb_pci_probe(struct pci_dev * pdev, + const struct pci_device_id * ent) +{ + struct fb_info * info[] = {NULL,NULL}; + struct lynx_share * share = NULL; + + struct sm750_share *spec_share = NULL; + size_t spec_offset = 0; + int fbidx; + + + /* enable device */ + if(pci_enable_device(pdev)){ + pr_err("can not enable device.\n"); + goto err_enable; + } + + /* though offset of share in sm750_share is 0, + * we use this marcro as the same */ + spec_offset = offsetof(struct sm750_share,share); + + spec_share = kzalloc(sizeof(*spec_share),GFP_KERNEL); + if(!spec_share){ + pr_err("Could not allocate memory for share.\n"); + goto err_share; + } + + /* setting share structure */ + share = (struct lynx_share * )(&(spec_share->share)); + share->fbinfo[0] = share->fbinfo[1] = NULL; + share->devid = pdev->device; + share->revid = pdev->revision; + + pr_info("share->revid = %02x\n",share->revid); + share->pdev = pdev; +#ifdef CONFIG_MTRR + share->mtrr_off = g_nomtrr; + share->mtrr.vram = 0; + share->mtrr.vram_added = 0; +#endif + share->accel_off = g_noaccel; + share->dual = g_dualview; + spin_lock_init(&share->slock); + + if(!share->accel_off){ + /* hook deInit and 2d routines, notes that below hw_xxx + * routine can work on most of lynx chips + * if some chip need specific function,please hook it in smXXX_set_drv + * routine */ + share->accel.de_init = hw_de_init; + share->accel.de_fillrect = hw_fillrect; + share->accel.de_copyarea = hw_copyarea; + share->accel.de_imageblit = hw_imageblit; + pr_info("enable 2d acceleration\n"); + }else{ + pr_info("disable 2d acceleration\n"); + } + + /* call chip specific setup routine */ + sm750fb_setup(share,g_settings); + + /* call chip specific mmap routine */ + if(hw_sm750_map(share,pdev)){ + pr_err("Memory map failed\n"); + goto err_map; + } + +#ifdef CONFIG_MTRR + if(!share->mtrr_off){ + pr_info("enable mtrr\n"); + share->mtrr.vram = mtrr_add(share->vidmem_start, + share->vidmem_size, + MTRR_TYPE_WRCOMB,1); + + if(share->mtrr.vram < 0){ + /* don't block driver with the failure of MTRR */ + pr_err("Unable to setup MTRR.\n"); + }else{ + share->mtrr.vram_added = 1; + pr_info("MTRR added succesfully\n"); + } + } +#endif + + memset(share->pvMem,0,share->vidmem_size); + + pr_info("sm%3x mmio address = %p\n",share->devid,share->pvReg); + + pci_set_drvdata(pdev,share); + + /* call chipInit routine */ + hw_sm750_inithw(share,pdev); + + /* allocate frame buffer info structor according to g_dualview */ + fbidx = 0; +ALLOC_FB: + info[fbidx] = framebuffer_alloc(sizeof(struct lynxfb_par),&pdev->dev); + if(!info[fbidx]) + { + pr_err("Could not allocate framebuffer #%d.\n",fbidx); + if(fbidx == 0) + goto err_info0_alloc; + else + goto err_info1_alloc; + } + else + { + struct lynxfb_par * par; + pr_info("framebuffer #%d alloc okay\n",fbidx); + share->fbinfo[fbidx] = info[fbidx]; + par = info[fbidx]->par; + par->share = share; + + /* set fb_info structure */ + if(lynxfb_set_fbinfo(info[fbidx],fbidx)){ + pr_err("Failed to initial fb_info #%d.\n",fbidx); + if(fbidx == 0) + goto err_info0_set; + else + goto err_info1_set; + } + + /* register frame buffer*/ + pr_info("Ready to register framebuffer #%d.\n",fbidx); + int errno = register_framebuffer(info[fbidx]); + if (errno < 0) { + pr_err("Failed to register fb_info #%d. err %d\n",fbidx, errno); + if(fbidx == 0) + goto err_register0; + else + goto err_register1; + } + pr_info("Accomplished register framebuffer #%d.\n",fbidx); + } + + /* no dual view by far */ + fbidx++; + if(share->dual && fbidx < 2) + goto ALLOC_FB; + + return 0; + +err_register1: +err_info1_set: + framebuffer_release(info[1]); +err_info1_alloc: + unregister_framebuffer(info[0]); +err_register0: +err_info0_set: + framebuffer_release(info[0]); +err_info0_alloc: +err_map: + kfree(spec_share); +err_share: +err_enable: + return -ENODEV; +} + +static void __exit lynxfb_pci_remove(struct pci_dev * pdev) +{ + struct fb_info * info; + struct lynx_share * share; + void * spec_share; + struct lynxfb_par * par; + int cnt; + + cnt = 2; + share = pci_get_drvdata(pdev); + + while(cnt-- > 0){ + info = share->fbinfo[cnt]; + if(!info) + continue; + par = info->par; + + unregister_framebuffer(info); + /* clean crtc & output allocations*/ + par->crtc.clear(&par->crtc); + par->output.clear(&par->output); + /* release frame buffer*/ + framebuffer_release(info); + } +#ifdef CONFIG_MTRR + if(share->mtrr.vram_added) + mtrr_del(share->mtrr.vram,share->vidmem_start,share->vidmem_size); +#endif + // pci_release_regions(pdev); + + iounmap(share->pvReg); + iounmap(share->pvMem); + spec_share = container_of(share,struct sm750_share,share); + kfree(g_settings); + kfree(spec_share); + pci_set_drvdata(pdev,NULL); +} + +static int __init lynxfb_setup(char * options) +{ + int len; + char * opt,*tmp; + + + if(!options || !*options){ + pr_warn("no options.\n"); + return 0; + } + + pr_info("options:%s\n",options); + + len = strlen(options) + 1; + g_settings = kmalloc(len,GFP_KERNEL); + if(!g_settings) + return -ENOMEM; + + memset(g_settings,0,len); + tmp = g_settings; + + /* Notes: + char * strsep(char **s,const char * ct); + @s: the string to be searched + @ct :the characters to search for + + strsep() updates @options to pointer after the first found token + it also returns the pointer ahead the token. + */ + while((opt = strsep(&options,":"))!=NULL) + { + /* options that mean for any lynx chips are configured here */ + if(!strncmp(opt,"noaccel",strlen("noaccel"))) + g_noaccel = 1; +#ifdef CONFIG_MTRR + else if(!strncmp(opt,"nomtrr",strlen("nomtrr"))) + g_nomtrr = 1; +#endif + else if(!strncmp(opt,"dual",strlen("dual"))) + g_dualview = 1; + else + { + strcat(tmp,opt); + tmp += strlen(opt); + if(options != NULL) + *tmp++ = ':'; + else + *tmp++ = 0; + } + } + + /* misc g_settings are transport to chip specific routines */ + pr_info("parameter left for chip specific analysis:%s\n",g_settings); + return 0; +} + +static struct pci_device_id smi_pci_table[] = { + { PCI_DEVICE(0x126f, 0x0750), }, + {0,} +}; + +MODULE_DEVICE_TABLE(pci,smi_pci_table); + +static struct pci_driver lynxfb_driver = { + .name = "sm750fb", + .id_table = smi_pci_table, + .probe = lynxfb_pci_probe, + .remove = lynxfb_pci_remove, +#ifdef CONFIG_PM + .suspend = lynxfb_suspend, + .resume = lynxfb_resume, +#endif +}; + + +static int __init lynxfb_init(void) +{ + char *option ; + int ret; + +#ifdef MODULE + option = g_option; +#else + if(fb_get_options("sm750fb",&option)) + return -ENODEV; +#endif + + lynxfb_setup(option); + ret = pci_register_driver(&lynxfb_driver); + return ret; +} +module_init(lynxfb_init); + +static void __exit lynxfb_exit(void) +{ + pci_unregister_driver(&lynxfb_driver); +} +module_exit(lynxfb_exit); + +module_param(g_option,charp,S_IRUGO); + +MODULE_PARM_DESC(g_option, + "\n\t\tCommon options:\n" + "\t\tnoaccel:disable 2d capabilities\n" + "\t\tnomtrr:disable MTRR attribute for video memory\n" + "\t\tdualview:dual frame buffer feature enabled\n" + "\t\tnohwc:disable hardware cursor\n" + "\t\tUsual example:\n" + "\t\tinsmod ./sm750fb.ko g_option=\"noaccel,nohwc,1280x1024-8@60\"\n" + ); + +MODULE_AUTHOR("monk liu "); +MODULE_AUTHOR("Sudip Mukherjee "); +MODULE_DESCRIPTION("Frame buffer driver for SM750 chipset"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h new file mode 100644 index 000000000000..711676c58839 --- /dev/null +++ b/drivers/staging/sm750fb/sm750.h @@ -0,0 +1,185 @@ +#ifndef LYNXDRV_H_ +#define LYNXDRV_H_ + + + +#define FB_ACCEL_SMI 0xab +/* please use revision id to distinguish sm750le and sm750*/ +#define SPC_SM750 0 + +//#define SPC_SM750LE 8 + +#define MB(x) ((x)<<20) +#define MHZ(x) ((x) * 1000000) +/* align should be 2,4,8,16 */ +#define PADDING(align,data) (((data)+(align)-1)&(~((align) -1))) +extern int smi_indent; + + +struct lynx_accel{ + /* base virtual address of DPR registers */ + volatile unsigned char __iomem * dprBase; + /* base virtual address of de data port */ + volatile unsigned char __iomem * dpPortBase; + + /* function fointers */ + int (*de_init)(struct lynx_accel *); + + int (*de_wait)(void);/* see if hardware ready to work */ + + int (*de_fillrect)(struct lynx_accel *,u32,u32,u32, + u32,u32,u32,u32,u32,u32); + + int (*de_copyarea)(struct lynx_accel *,u32,u32,u32,u32, + u32,u32,u32,u32, + u32,u32,u32,u32); + + int (*de_imageblit)(struct lynx_accel *,const char *,u32,u32,u32, + u32,u32,u32,u32,u32,u32,u32,u32,u32); + +}; + +/* lynx_share stands for a presentation of two frame buffer + that use one smi adaptor , it is similar to a basic class of C++ +*/ +struct lynx_share{ + /* common members */ + u16 devid; + u8 revid; + struct pci_dev * pdev; + struct fb_info * fbinfo[2]; + struct lynx_accel accel; + int accel_off; + int dual; +#ifdef CONFIG_MTRR + int mtrr_off; + struct{ + int vram; + int vram_added; + }mtrr; +#endif + /* all smi graphic adaptor got below attributes */ + resource_size_t vidmem_start; + resource_size_t vidreg_start; + resource_size_t vidmem_size; + resource_size_t vidreg_size; + volatile unsigned char __iomem * pvReg; + unsigned char __iomem * pvMem; + /* locks*/ + spinlock_t slock; + /* function pointers */ + void (*suspend)(struct lynx_share*); + void (*resume)(struct lynx_share*); +}; + +struct lynx_cursor{ + /* cursor width ,height and size */ + int w; + int h; + int size; + /* hardware limitation */ + int maxW; + int maxH; + /* base virtual address and offset of cursor image */ + char __iomem * vstart; + int offset; + /* mmio addr of hw cursor */ + volatile char __iomem * mmio; + /* the lynx_share of this adaptor */ + struct lynx_share * share; + /* proc_routines */ + void (*enable)(struct lynx_cursor *); + void (*disable)(struct lynx_cursor *); + void (*setSize)(struct lynx_cursor *,int,int); + void (*setPos)(struct lynx_cursor *,int,int); + void (*setColor)(struct lynx_cursor *,u32,u32); + void (*setData)(struct lynx_cursor *,u16,const u8*,const u8*); +}; + +struct lynxfb_crtc{ + unsigned char __iomem * vCursor;//virtual address of cursor + unsigned char __iomem * vScreen;//virtual address of on_screen + int oCursor;//cursor address offset in vidmem + int oScreen;//onscreen address offset in vidmem + int channel;/* which channel this crtc stands for*/ + resource_size_t vidmem_size;/* this view's video memory max size */ + + /* below attributes belong to info->fix, their value depends on specific adaptor*/ + u16 line_pad;/* padding information:0,1,2,4,8,16,... */ + u16 xpanstep; + u16 ypanstep; + u16 ywrapstep; + + void * priv; + + int(*proc_setMode)(struct lynxfb_crtc*, + struct fb_var_screeninfo*, + struct fb_fix_screeninfo*); + + int(*proc_checkMode)(struct lynxfb_crtc*,struct fb_var_screeninfo*); + int(*proc_setColReg)(struct lynxfb_crtc*,ushort,ushort,ushort,ushort); + void (*clear)(struct lynxfb_crtc*); + /* pan display */ + int(*proc_panDisplay)(struct lynxfb_crtc*, struct fb_var_screeninfo*, + struct fb_info*); + /* cursor information */ + struct lynx_cursor cursor; +}; + +struct lynxfb_output{ + int dpms; + int paths; + /* which paths(s) this output stands for,for sm750: + paths=1:means output for panel paths + paths=2:means output for crt paths + paths=3:means output for both panel and crt paths + */ + + int * channel; + /* which channel these outputs linked with,for sm750: + *channel=0 means primary channel + *channel=1 means secondary channel + output->channel ==> &crtc->channel + */ + void * priv; + + int(*proc_setMode)(struct lynxfb_output*, + struct fb_var_screeninfo*, + struct fb_fix_screeninfo*); + + int(*proc_checkMode)(struct lynxfb_output*,struct fb_var_screeninfo*); + int(*proc_setBLANK)(struct lynxfb_output*,int); + void (*clear)(struct lynxfb_output*); +}; + +struct lynxfb_par{ + /* either 0 or 1 for dual head adaptor,0 is the older one registered */ + int index; + unsigned int pseudo_palette[256]; + struct lynxfb_crtc crtc; + struct lynxfb_output output; + struct fb_info * info; + struct lynx_share * share; +}; + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + + +#define PS_TO_HZ(ps) \ + ({ \ + unsigned long long hz = 1000*1000*1000*1000ULL; \ + do_div(hz,ps); \ + (unsigned long)hz;}) + +static inline unsigned long ps_to_hz(unsigned int psvalue) +{ + unsigned long long numerator=1000*1000*1000*1000ULL; + /* 10^12 / picosecond period gives frequency in Hz */ + do_div(numerator, psvalue); + return (unsigned long)numerator; +} + + +#endif diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c new file mode 100644 index 000000000000..ee211deb9975 --- /dev/null +++ b/drivers/staging/sm750fb/sm750_accel.c @@ -0,0 +1,516 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sm750.h" +#include "sm750_accel.h" +#include "sm750_help.h" +static inline void write_dpr(struct lynx_accel * accel,int offset,u32 regValue) +{ + writel(regValue,accel->dprBase + offset); +} + +static inline u32 read_dpr(struct lynx_accel * accel,int offset) +{ + return readl(accel->dprBase + offset); +} + +static inline void write_dpPort(struct lynx_accel * accel,u32 data) +{ + writel(data,accel->dpPortBase); +} + +void hw_de_init(struct lynx_accel * accel) +{ + /* setup 2d engine registers */ + u32 reg,clr; + + write_dpr(accel,DE_MASKS,0xFFFFFFFF); + + /* dpr1c */ + reg = FIELD_SET(0,DE_STRETCH_FORMAT,PATTERN_XY,NORMAL)| + FIELD_VALUE(0,DE_STRETCH_FORMAT,PATTERN_Y,0)| + FIELD_VALUE(0,DE_STRETCH_FORMAT,PATTERN_X,0)| + FIELD_SET(0,DE_STRETCH_FORMAT,ADDRESSING,XY)| + FIELD_VALUE(0,DE_STRETCH_FORMAT,SOURCE_HEIGHT,3); + + clr = FIELD_CLEAR(DE_STRETCH_FORMAT,PATTERN_XY)& + FIELD_CLEAR(DE_STRETCH_FORMAT,PATTERN_Y)& + FIELD_CLEAR(DE_STRETCH_FORMAT,PATTERN_X)& + FIELD_CLEAR(DE_STRETCH_FORMAT,ADDRESSING)& + FIELD_CLEAR(DE_STRETCH_FORMAT,SOURCE_HEIGHT); + + /* DE_STRETCH bpp format need be initilized in setMode routine */ + write_dpr(accel,DE_STRETCH_FORMAT,(read_dpr(accel,DE_STRETCH_FORMAT) & clr) | reg); + + /* disable clipping and transparent */ + write_dpr(accel,DE_CLIP_TL,0);//dpr2c + write_dpr(accel,DE_CLIP_BR,0);//dpr30 + + write_dpr(accel,DE_COLOR_COMPARE_MASK,0);//dpr24 + write_dpr(accel,DE_COLOR_COMPARE,0); + + reg = FIELD_SET(0,DE_CONTROL,TRANSPARENCY,DISABLE)| + FIELD_SET(0,DE_CONTROL,TRANSPARENCY_MATCH,OPAQUE)| + FIELD_SET(0,DE_CONTROL,TRANSPARENCY_SELECT,SOURCE); + + clr = FIELD_CLEAR(DE_CONTROL,TRANSPARENCY)& + FIELD_CLEAR(DE_CONTROL,TRANSPARENCY_MATCH)& + FIELD_CLEAR(DE_CONTROL,TRANSPARENCY_SELECT); + + /* dpr0c */ + write_dpr(accel,DE_CONTROL,(read_dpr(accel,DE_CONTROL)&clr)|reg); +} + +/* set2dformat only be called from setmode functions + * but if you need dual framebuffer driver,need call set2dformat + * every time you use 2d function */ + +void hw_set2dformat(struct lynx_accel * accel,int fmt) +{ + u32 reg; + + /* fmt=0,1,2 for 8,16,32,bpp on sm718/750/502 */ + reg = read_dpr(accel,DE_STRETCH_FORMAT); + reg = FIELD_VALUE(reg,DE_STRETCH_FORMAT,PIXEL_FORMAT,fmt); + write_dpr(accel,DE_STRETCH_FORMAT,reg); +} + +/* seems sm712 RectFill command is broken,so need use BitBlt to + * replace it. */ + +int hw712_fillrect(struct lynx_accel * accel, + u32 base,u32 pitch,u32 Bpp, + u32 x,u32 y,u32 width,u32 height, + u32 color,u32 rop) +{ + u32 deCtrl; + if(accel->de_wait() != 0) + { + /* int time wait and always busy,seems hardware + * got something error */ + pr_debug("%s:De engine always bussy\n",__func__); + return -1; + } + /* 24bpp 2d acceleration still not work,we already support 2d on + * both 8/16/32 bpp now, so there is no harm if we disable 2d on + * 24bpp for current stage. */ +#if 0 + if(Bpp == 3){ + width *= 3; + x *= 3; + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0,DE_PITCH,DESTINATION,pitch)| + FIELD_VALUE(0,DE_PITCH,SOURCE,pitch));//dpr10 + } + else +#endif + { + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0,DE_PITCH,DESTINATION,pitch/Bpp)| + FIELD_VALUE(0,DE_PITCH,SOURCE,pitch/Bpp));//dpr10 + + } + + write_dpr(accel,DE_FOREGROUND,color);//DPR14 + write_dpr(accel,DE_MONO_PATTERN_HIGH,~0);//DPR34 + write_dpr(accel,DE_MONO_PATTERN_LOW,~0);//DPR38 + + write_dpr(accel,DE_WINDOW_SOURCE_BASE,base);//dpr44 + write_dpr(accel,DE_WINDOW_DESTINATION_BASE,base);//dpr40 + + + write_dpr(accel,DE_WINDOW_WIDTH, + FIELD_VALUE(0,DE_WINDOW_WIDTH,DESTINATION,pitch/Bpp)| + FIELD_VALUE(0,DE_WINDOW_WIDTH,SOURCE,pitch/Bpp));//dpr3c + + + write_dpr(accel,DE_DESTINATION, + FIELD_SET(0,DE_DESTINATION,WRAP,DISABLE)| + FIELD_VALUE(0,DE_DESTINATION,X,x)| + FIELD_VALUE(0,DE_DESTINATION,Y,y));//dpr4 + + write_dpr(accel,DE_DIMENSION, + FIELD_VALUE(0,DE_DIMENSION,X,width)| + FIELD_VALUE(0,DE_DIMENSION,Y_ET,height));//dpr8 + + deCtrl = + FIELD_SET(0,DE_CONTROL,STATUS,START)| + FIELD_SET(0,DE_CONTROL,COMMAND,BITBLT)| + FIELD_SET(0,DE_CONTROL,ROP2_SOURCE,PATTERN)| + FIELD_SET(0,DE_CONTROL,ROP_SELECT,ROP2)| + FIELD_VALUE(0,DE_CONTROL,ROP,rop);//dpr0xc +#if 0 + /* dump registers */ + int i; + inf_msg("x,y,w,h = %d,%d,%d,%d\n",x,y,width,height); + for(i=0x04;i<=0x44;i+=4){ + inf_msg("dpr%02x = %08x\n",i,read_dpr(accel,i)); + } + inf_msg("deCtrl = %08x\n",deCtrl); +#endif + + write_dpr(accel,DE_CONTROL,deCtrl); + return 0; +} + +int hw_fillrect(struct lynx_accel * accel, + u32 base,u32 pitch,u32 Bpp, + u32 x,u32 y,u32 width,u32 height, + u32 color,u32 rop) +{ + u32 deCtrl; + + if(accel->de_wait() != 0) + { + /* int time wait and always busy,seems hardware + * got something error */ + pr_debug("%s:De engine always bussy\n",__func__); + return -1; + } + + write_dpr(accel,DE_WINDOW_DESTINATION_BASE,base);//dpr40 + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0,DE_PITCH,DESTINATION,pitch/Bpp)| + FIELD_VALUE(0,DE_PITCH,SOURCE,pitch/Bpp));//dpr10 + + write_dpr(accel,DE_WINDOW_WIDTH, + FIELD_VALUE(0,DE_WINDOW_WIDTH,DESTINATION,pitch/Bpp)| + FIELD_VALUE(0,DE_WINDOW_WIDTH,SOURCE,pitch/Bpp));//dpr44 + + write_dpr(accel,DE_FOREGROUND,color);//DPR14 + + write_dpr(accel,DE_DESTINATION, + FIELD_SET(0,DE_DESTINATION,WRAP,DISABLE)| + FIELD_VALUE(0,DE_DESTINATION,X,x)| + FIELD_VALUE(0,DE_DESTINATION,Y,y));//dpr4 + + write_dpr(accel,DE_DIMENSION, + FIELD_VALUE(0,DE_DIMENSION,X,width)| + FIELD_VALUE(0,DE_DIMENSION,Y_ET,height));//dpr8 + + deCtrl = + FIELD_SET(0,DE_CONTROL,STATUS,START)| + FIELD_SET(0,DE_CONTROL,DIRECTION,LEFT_TO_RIGHT)| + FIELD_SET(0,DE_CONTROL,LAST_PIXEL,ON)| + FIELD_SET(0,DE_CONTROL,COMMAND,RECTANGLE_FILL)| + FIELD_SET(0,DE_CONTROL,ROP_SELECT,ROP2)| + FIELD_VALUE(0,DE_CONTROL,ROP,rop);//dpr0xc + + write_dpr(accel,DE_CONTROL,deCtrl); + return 0; +} + +int hw_copyarea( +struct lynx_accel * accel, +unsigned int sBase, /* Address of source: offset in frame buffer */ +unsigned int sPitch, /* Pitch value of source surface in BYTE */ +unsigned int sx, +unsigned int sy, /* Starting coordinate of source surface */ +unsigned int dBase, /* Address of destination: offset in frame buffer */ +unsigned int dPitch, /* Pitch value of destination surface in BYTE */ +unsigned int Bpp, /* Color depth of destination surface */ +unsigned int dx, +unsigned int dy, /* Starting coordinate of destination surface */ +unsigned int width, +unsigned int height, /* width and height of rectangle in pixel value */ +unsigned int rop2) /* ROP value */ +{ + unsigned int nDirection, de_ctrl; + int opSign; + nDirection = LEFT_TO_RIGHT; + /* Direction of ROP2 operation: 1 = Left to Right, (-1) = Right to Left */ + opSign = 1; + de_ctrl = 0; + + /* If source and destination are the same surface, need to check for overlay cases */ + if (sBase == dBase && sPitch == dPitch) + { + /* Determine direction of operation */ + if (sy < dy) + { + /* +----------+ + |S | + | +----------+ + | | | | + | | | | + +---|------+ | + | D| + +----------+ */ + + nDirection = BOTTOM_TO_TOP; + } + else if (sy > dy) + { + /* +----------+ + |D | + | +----------+ + | | | | + | | | | + +---|------+ | + | S| + +----------+ */ + + nDirection = TOP_TO_BOTTOM; + } + else + { + /* sy == dy */ + + if (sx <= dx) + { + /* +------+---+------+ + |S | | D| + | | | | + | | | | + | | | | + +------+---+------+ */ + + nDirection = RIGHT_TO_LEFT; + } + else + { + /* sx > dx */ + + /* +------+---+------+ + |D | | S| + | | | | + | | | | + | | | | + +------+---+------+ */ + + nDirection = LEFT_TO_RIGHT; + } + } + } + + if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) + { + sx += width - 1; + sy += height - 1; + dx += width - 1; + dy += height - 1; + opSign = (-1); + } + + /* Note: + DE_FOREGROUND are DE_BACKGROUND are don't care. + DE_COLOR_COMPARE and DE_COLOR_COMPARE_MAKS are set by set deSetTransparency(). + */ + + /* 2D Source Base. + It is an address offset (128 bit aligned) from the beginning of frame buffer. + */ + write_dpr(accel,DE_WINDOW_SOURCE_BASE, sBase);//dpr40 + + /* 2D Destination Base. + It is an address offset (128 bit aligned) from the beginning of frame buffer. + */ + write_dpr(accel,DE_WINDOW_DESTINATION_BASE, dBase);//dpr44 + +#if 0 + /* Program pitch (distance between the 1st points of two adjacent lines). + Note that input pitch is BYTE value, but the 2D Pitch register uses + pixel values. Need Byte to pixel convertion. + */ + if(Bpp == 3){ + sx *= 3; + dx *= 3; + width *= 3; + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dPitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, sPitch));//dpr10 + } + else +#endif + { + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, (dPitch/Bpp)) | + FIELD_VALUE(0, DE_PITCH, SOURCE, (sPitch/Bpp)));//dpr10 + } + + /* Screen Window width in Pixels. + 2D engine uses this value to calculate the linear address in frame buffer for a given point. + */ + write_dpr(accel,DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, (dPitch/Bpp)) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, (sPitch/Bpp)));//dpr3c + + if (accel->de_wait() != 0){ + return -1; + } + + { + + write_dpr(accel,DE_SOURCE, + FIELD_SET (0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, sx) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, sy));//dpr0 + write_dpr(accel,DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dx) | + FIELD_VALUE(0, DE_DESTINATION, Y, dy));//dpr04 + write_dpr(accel,DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));//dpr08 + + de_ctrl = + FIELD_VALUE(0, DE_CONTROL, ROP, rop2) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) | + ((nDirection == RIGHT_TO_LEFT) ? + FIELD_SET(0, DE_CONTROL, DIRECTION, RIGHT_TO_LEFT) + : FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT)) | + FIELD_SET(0, DE_CONTROL, STATUS, START); + write_dpr(accel,DE_CONTROL,de_ctrl);//dpr0c + } + + return 0; +} + +static unsigned int deGetTransparency(struct lynx_accel * accel) +{ + unsigned int de_ctrl; + + de_ctrl = read_dpr(accel,DE_CONTROL); + + de_ctrl &= + FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) | + FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT)| + FIELD_MASK(DE_CONTROL_TRANSPARENCY); + + return de_ctrl; +} + +int hw_imageblit( +struct lynx_accel * accel, +unsigned char *pSrcbuf, /* pointer to start of source buffer in system memory */ +int srcDelta, /* Pitch value (in bytes) of the source buffer, +ive means top down and -ive mean button up */ +unsigned int startBit, /* Mono data can start at any bit in a byte, this value should be 0 to 7 */ +unsigned int dBase, /* Address of destination: offset in frame buffer */ +unsigned int dPitch, /* Pitch value of destination surface in BYTE */ +unsigned int bytePerPixel, /* Color depth of destination surface */ +unsigned int dx, +unsigned int dy, /* Starting coordinate of destination surface */ +unsigned int width, +unsigned int height, /* width and height of rectange in pixel value */ +unsigned int fColor, /* Foreground color (corresponding to a 1 in the monochrome data */ +unsigned int bColor, /* Background color (corresponding to a 0 in the monochrome data */ +unsigned int rop2) /* ROP value */ +{ + unsigned int ulBytesPerScan; + unsigned int ul4BytesPerScan; + unsigned int ulBytesRemain; + unsigned int de_ctrl = 0; + unsigned char ajRemain[4]; + int i, j; + + startBit &= 7; /* Just make sure the start bit is within legal range */ + ulBytesPerScan = (width + startBit + 7) / 8; + ul4BytesPerScan = ulBytesPerScan & ~3; + ulBytesRemain = ulBytesPerScan & 3; + + if(accel->de_wait() != 0) + { +// inf_msg("*** ImageBlit return -1 ***\n"); + return -1; + } + + /* 2D Source Base. + Use 0 for HOST Blt. + */ + write_dpr(accel,DE_WINDOW_SOURCE_BASE, 0); + + /* 2D Destination Base. + It is an address offset (128 bit aligned) from the beginning of frame buffer. + */ + write_dpr(accel,DE_WINDOW_DESTINATION_BASE, dBase); +#if 0 + /* Program pitch (distance between the 1st points of two adjacent lines). + Note that input pitch is BYTE value, but the 2D Pitch register uses + pixel values. Need Byte to pixel convertion. + */ + if(bytePerPixel == 3 ){ + dx *= 3; + width *= 3; + startBit *= 3; + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dPitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dPitch));//dpr10 + + } + else +#endif + { + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dPitch/bytePerPixel) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dPitch/bytePerPixel));//dpr10 + } + + /* Screen Window width in Pixels. + 2D engine uses this value to calculate the linear address in frame buffer for a given point. + */ + write_dpr(accel,DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, (dPitch/bytePerPixel)) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, (dPitch/bytePerPixel))); + + /* Note: For 2D Source in Host Write, only X_K1_MONO field is needed, and Y_K2 field is not used. + For mono bitmap, use startBit for X_K1. */ + write_dpr(accel,DE_SOURCE, + FIELD_SET (0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1_MONO, startBit));//dpr00 + + write_dpr(accel,DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dx) | + FIELD_VALUE(0, DE_DESTINATION, Y, dy));//dpr04 + + write_dpr(accel,DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));//dpr08 + + write_dpr(accel,DE_FOREGROUND, fColor); + write_dpr(accel,DE_BACKGROUND, bColor); + + de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) | + FIELD_SET(0, DE_CONTROL, HOST, MONO) | + FIELD_SET(0, DE_CONTROL, STATUS, START); + + write_dpr(accel,DE_CONTROL, de_ctrl | deGetTransparency(accel)); + + /* Write MONO data (line by line) to 2D Engine data port */ + for (i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sm750.h" +#include "sm750_help.h" +#include "sm750_cursor.h" + + +#define PEEK32(addr) \ +readl(cursor->mmio + (addr)) + +#define POKE32(addr,data) \ +writel((data),cursor->mmio + (addr)) + +/* cursor control for voyager and 718/750*/ +#define HWC_ADDRESS 0x0 +#define HWC_ADDRESS_ENABLE 31:31 +#define HWC_ADDRESS_ENABLE_DISABLE 0 +#define HWC_ADDRESS_ENABLE_ENABLE 1 +#define HWC_ADDRESS_EXT 27:27 +#define HWC_ADDRESS_EXT_LOCAL 0 +#define HWC_ADDRESS_EXT_EXTERNAL 1 +#define HWC_ADDRESS_CS 26:26 +#define HWC_ADDRESS_CS_0 0 +#define HWC_ADDRESS_CS_1 1 +#define HWC_ADDRESS_ADDRESS 25:0 + +#define HWC_LOCATION 0x4 +#define HWC_LOCATION_TOP 27:27 +#define HWC_LOCATION_TOP_INSIDE 0 +#define HWC_LOCATION_TOP_OUTSIDE 1 +#define HWC_LOCATION_Y 26:16 +#define HWC_LOCATION_LEFT 11:11 +#define HWC_LOCATION_LEFT_INSIDE 0 +#define HWC_LOCATION_LEFT_OUTSIDE 1 +#define HWC_LOCATION_X 10:0 + +#define HWC_COLOR_12 0x8 +#define HWC_COLOR_12_2_RGB565 31:16 +#define HWC_COLOR_12_1_RGB565 15:0 + +#define HWC_COLOR_3 0xC +#define HWC_COLOR_3_RGB565 15:0 + + +/* hw_cursor_xxx works for voyager,718 and 750 */ +void hw_cursor_enable(struct lynx_cursor * cursor) +{ + u32 reg; + reg = FIELD_VALUE(0,HWC_ADDRESS,ADDRESS,cursor->offset)| + FIELD_SET(0,HWC_ADDRESS,EXT,LOCAL)| + FIELD_SET(0,HWC_ADDRESS,ENABLE,ENABLE); + POKE32(HWC_ADDRESS,reg); +} +void hw_cursor_disable(struct lynx_cursor * cursor) +{ + POKE32(HWC_ADDRESS,0); +} + +void hw_cursor_setSize(struct lynx_cursor * cursor, + int w,int h) +{ + cursor->w = w; + cursor->h = h; +} +void hw_cursor_setPos(struct lynx_cursor * cursor, + int x,int y) +{ + u32 reg; + reg = FIELD_VALUE(0,HWC_LOCATION,Y,y)| + FIELD_VALUE(0,HWC_LOCATION,X,x); + POKE32(HWC_LOCATION,reg); +} +void hw_cursor_setColor(struct lynx_cursor * cursor, + u32 fg,u32 bg) +{ + POKE32(HWC_COLOR_12,(fg<<16)|(bg&0xffff)); + POKE32(HWC_COLOR_3,0xffe0); +} + +void hw_cursor_setData(struct lynx_cursor * cursor, + u16 rop,const u8* pcol,const u8* pmsk) +{ + int i,j,count,pitch,offset; + u8 color,mask,opr; + u16 data; + u16 * pbuffer,*pstart; + static ulong odd = 0; + + /* in byte*/ + pitch = cursor->w >> 3; + + /* in byte */ + count = pitch * cursor->h; + + /* in ushort */ + offset = cursor->maxW * 2 / 8 / 2; + + data = 0; + pstart = (u16 *)cursor->vstart; + pbuffer = pstart; + +/* + if(odd &1){ + hw_cursor_setData2(cursor,rop,pcol,pmsk); + } + odd++; + if(odd > 0xfffffff0) + odd=0; +*/ + + for(i=0;i> j)) + { //use fg color,id = 2 + data |= 2 << (j*2); + }else{ + //use bg color,id = 1 + data |= 1 << (j*2); + } + } +#else + for(j=0;j<8;j++){ + if(mask & (0x80>>j)){ + if(rop == ROP_XOR) + opr = mask ^ color; + else + opr = mask & color; + + /* 2 stands for forecolor and 1 for backcolor */ + data |= ((opr & (0x80>>j))?2:1)<<(j*2); + } + } +#endif + *pbuffer = data; + + /* assume pitch is 1,2,4,8,...*/ +#if 0 + if(!((i+1)&(pitch-1))) /* below line equal to is line */ +#else + if((i+1) % pitch == 0) +#endif + { + /* need a return */ + pstart += offset; + pbuffer = pstart; + }else{ + pbuffer++; + } + + } + + +} + + +void hw_cursor_setData2(struct lynx_cursor * cursor, + u16 rop,const u8* pcol,const u8* pmsk) +{ + int i,j,count,pitch,offset; + u8 color,mask,opr; + u16 data; + u16 * pbuffer,*pstart; + + /* in byte*/ + pitch = cursor->w >> 3; + + /* in byte */ + count = pitch * cursor->h; + + /* in ushort */ + offset = cursor->maxW * 2 / 8 / 2; + + data = 0; + pstart = (u16 *)cursor->vstart; + pbuffer = pstart; + + for(i=0;i> j)) + { //use fg color,id = 2 + data |= 2 << (j*2); + }else{ + //use bg color,id = 1 + data |= 1 << (j*2); + } + } +#else + for(j=0;j<8;j++){ + if(mask & (1<> (32 - _COUNT(f))) +#define GET_MASK(f) (RAW_MASK(f) << _LSB(f)) +#define GET_FIELD(d,f) (((d) >> _LSB(f)) & RAW_MASK(f)) +#define TEST_FIELD(d,f,v) (GET_FIELD(d,f) == f ## _ ## v) +#define SET_FIELD(d,f,v) (((d) & ~GET_MASK(f)) | \ + (((f ## _ ## v) & RAW_MASK(f)) << _LSB(f))) +#define SET_FIELDV(d,f,v) (((d) & ~GET_MASK(f)) | \ + (((v) & RAW_MASK(f)) << _LSB(f))) + + +//////////////////////////////////////////////////////////////////////////////// +// // +// Internal macros // +// // +//////////////////////////////////////////////////////////////////////////////// + +#define _F_START(f) (0 ? f) +#define _F_END(f) (1 ? f) +#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f)) +#define _F_MASK(f) (((1 << _F_SIZE(f)) - 1) << _F_START(f)) +#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f)) +#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f)) + + +//////////////////////////////////////////////////////////////////////////////// +// // +// Global macros // +// // +//////////////////////////////////////////////////////////////////////////////// + +#define FIELD_GET(x, reg, field) \ +( \ + _F_NORMALIZE((x), reg ## _ ## field) \ +) + +#define FIELD_SET(x, reg, field, value) \ +( \ + (x & ~_F_MASK(reg ## _ ## field)) \ + | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \ +) + +#define FIELD_VALUE(x, reg, field, value) \ +( \ + (x & ~_F_MASK(reg ## _ ## field)) \ + | _F_DENORMALIZE(value, reg ## _ ## field) \ +) + +#define FIELD_CLEAR(reg, field) \ +( \ + ~ _F_MASK(reg ## _ ## field) \ +) + + +//////////////////////////////////////////////////////////////////////////////// +// // +// Field Macros // +// // +//////////////////////////////////////////////////////////////////////////////// + +#define FIELD_START(field) (0 ? field) +#define FIELD_END(field) (1 ? field) +#define FIELD_SIZE(field) (1 + FIELD_END(field) - FIELD_START(field)) +#define FIELD_MASK(field) (((1 << (FIELD_SIZE(field)-1)) | ((1 << (FIELD_SIZE(field)-1)) - 1)) << FIELD_START(field)) +#define FIELD_NORMALIZE(reg, field) (((reg) & FIELD_MASK(field)) >> FIELD_START(field)) +#define FIELD_DENORMALIZE(field, value) (((value) << FIELD_START(field)) & FIELD_MASK(field)) + +#define FIELD_INIT(reg, field, value) FIELD_DENORMALIZE(reg ## _ ## field, \ + reg ## _ ## field ## _ ## value) +#define FIELD_INIT_VAL(reg, field, value) \ + (FIELD_DENORMALIZE(reg ## _ ## field, value)) +#define FIELD_VAL_SET(x, r, f, v) x = x & ~FIELD_MASK(r ## _ ## f) \ + | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) + +#define RGB(r, g, b) \ +( \ + (unsigned long) (((r) << 16) | ((g) << 8) | (b)) \ +) + +#define RGB16(r, g, b) \ +( \ + (unsigned short) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3)) \ +) + +static inline unsigned int absDiff(unsigned int a,unsigned int b) +{ + if(a +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MTRR +#include +#endif +#include +#include + +#include "sm750.h" +#include "sm750_hw.h" +#include "ddk750.h" +#include "sm750_accel.h" + +int hw_sm750_map(struct lynx_share* share,struct pci_dev* pdev) +{ + int ret; + struct sm750_share * spec_share; + + + spec_share = container_of(share,struct sm750_share,share); + ret = 0; + + share->vidreg_start = pci_resource_start(pdev,1); + share->vidreg_size = MB(2); + + pr_info("mmio phyAddr = %x\n",share->vidreg_start); + + /* reserve the vidreg space of smi adaptor + * if you do this, u need to add release region code + * in lynxfb_remove, or memory will not be mapped again + * successfully + * */ + + if((ret = pci_request_region(pdev,1,"sm750fb"))) + { + pr_err("Can not request PCI regions.\n"); + goto exit; + } + + /* now map mmio and vidmem*/ + share->pvReg = ioremap_nocache(share->vidreg_start,share->vidreg_size); + if(!share->pvReg){ + pr_err("mmio failed\n"); + ret = -EFAULT; + goto exit; + }else{ + pr_info("mmio virtual addr = %p\n",share->pvReg); + } + + + share->accel.dprBase = share->pvReg + DE_BASE_ADDR_TYPE1; + share->accel.dpPortBase = share->pvReg + DE_PORT_ADDR_TYPE1; + + ddk750_set_mmio(share->pvReg,share->devid,share->revid); + + share->vidmem_start = pci_resource_start(pdev,0); + /* don't use pdev_resource[x].end - resource[x].start to + * calculate the resource size,its only the maximum available + * size but not the actual size,use + * @hw_sm750_getVMSize function can be safe. + * */ + share->vidmem_size = hw_sm750_getVMSize(share); + pr_info("video memory phyAddr = %x, size = %d bytes\n", + share->vidmem_start,share->vidmem_size); + + /* reserve the vidmem space of smi adaptor */ +#if 0 + if((ret = pci_request_region(pdev,0,_moduleName_))) + { + pr_err("Can not request PCI regions.\n"); + goto exit; + } +#endif + + share->pvMem = ioremap(share->vidmem_start, + share->vidmem_size); + + if(!share->pvMem){ + pr_err("Map video memory failed\n"); + ret = -EFAULT; + goto exit; + }else{ + pr_info("video memory vaddr = %p\n",share->pvMem); + } +exit: + return ret; +} + + + +int hw_sm750_inithw(struct lynx_share* share,struct pci_dev * pdev) +{ + struct sm750_share * spec_share; + struct init_status * parm; + + spec_share = container_of(share,struct sm750_share,share); + parm = &spec_share->state.initParm; + if(parm->chip_clk == 0) + parm->chip_clk = (getChipType() == SM750LE)? + DEFAULT_SM750LE_CHIP_CLOCK : + DEFAULT_SM750_CHIP_CLOCK; + + if(parm->mem_clk == 0) + parm->mem_clk = parm->chip_clk; + if(parm->master_clk == 0) + parm->master_clk = parm->chip_clk/3; + + ddk750_initHw((initchip_param_t *)&spec_share->state.initParm); + /* for sm718,open pci burst */ + if(share->devid == 0x718){ + POKE32(SYSTEM_CTRL, + FIELD_SET(PEEK32(SYSTEM_CTRL),SYSTEM_CTRL,PCI_BURST,ON)); + } + + /* sm750 use sii164, it can be setup with default value + * by on power, so initDVIDisp can be skipped */ +#if 0 + ddk750_initDVIDisp(); +#endif + + if(getChipType() != SM750LE) + { + /* does user need CRT ?*/ + if(spec_share->state.nocrt){ + POKE32(MISC_CTRL, + FIELD_SET(PEEK32(MISC_CTRL), + MISC_CTRL, + DAC_POWER,OFF)); + /* shut off dpms */ + POKE32(SYSTEM_CTRL, + FIELD_SET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + DPMS,VNHN)); + }else{ + POKE32(MISC_CTRL, + FIELD_SET(PEEK32(MISC_CTRL), + MISC_CTRL, + DAC_POWER,ON)); + /* turn on dpms */ + POKE32(SYSTEM_CTRL, + FIELD_SET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + DPMS,VPHP)); + } + + switch (spec_share->state.pnltype){ + case sm750_doubleTFT: + case sm750_24TFT: + case sm750_dualTFT: + POKE32(PANEL_DISPLAY_CTRL, + FIELD_VALUE(PEEK32(PANEL_DISPLAY_CTRL), + PANEL_DISPLAY_CTRL, + TFT_DISP, + spec_share->state.pnltype)); + break; + } + }else{ + /* for 750LE ,no DVI chip initilization makes Monitor no signal */ + /* Set up GPIO for software I2C to program DVI chip in the + Xilinx SP605 board, in order to have video signal. + */ + swI2CInit(0,1); + + + /* Customer may NOT use CH7301 DVI chip, which has to be + initialized differently. + */ + if (swI2CReadReg(0xec, 0x4a) == 0x95) + { + /* The following register values for CH7301 are from + Chrontel app note and our experiment. + */ + pr_info("yes,CH7301 DVI chip found\n"); + swI2CWriteReg(0xec, 0x1d, 0x16); + swI2CWriteReg(0xec, 0x21, 0x9); + swI2CWriteReg(0xec, 0x49, 0xC0); + pr_info("okay,CH7301 DVI chip setup done\n"); + } + } + + /* init 2d engine */ + if(!share->accel_off){ + hw_sm750_initAccel(share); +// share->accel.de_wait = hw_sm750_deWait; + } + + return 0; +} + + +resource_size_t hw_sm750_getVMSize(struct lynx_share * share) +{ + resource_size_t ret; + + ret = ddk750_getVMSize(); + return ret; +} + + + +int hw_sm750_output_checkMode(struct lynxfb_output* output,struct fb_var_screeninfo* var) +{ + + return 0; +} + + +int hw_sm750_output_setMode(struct lynxfb_output* output, + struct fb_var_screeninfo* var,struct fb_fix_screeninfo* fix) +{ + int ret; + disp_output_t dispSet; + int channel; + + ret = 0; + dispSet = 0; + channel = *output->channel; + + + if(getChipType() != SM750LE){ + if(channel == sm750_primary){ + pr_info("primary channel\n"); + if(output->paths & sm750_panel) + dispSet |= do_LCD1_PRI; + if(output->paths & sm750_crt) + dispSet |= do_CRT_PRI; + + }else{ + pr_info("secondary channel\n"); + if(output->paths & sm750_panel) + dispSet |= do_LCD1_SEC; + if(output->paths & sm750_crt) + dispSet |= do_CRT_SEC; + + } + ddk750_setLogicalDispOut(dispSet); + }else{ + /* just open DISPLAY_CONTROL_750LE register bit 3:0*/ + u32 reg; + reg = PEEK32(DISPLAY_CONTROL_750LE); + reg |= 0xf; + POKE32(DISPLAY_CONTROL_750LE,reg); + } + + pr_info("ddk setlogicdispout done \n"); + return ret; +} + +void hw_sm750_output_clear(struct lynxfb_output* output) +{ + + return; +} + +int hw_sm750_crtc_checkMode(struct lynxfb_crtc* crtc,struct fb_var_screeninfo* var) +{ + struct lynx_share * share; + + + share = container_of(crtc,struct lynxfb_par,crtc)->share; + + switch (var->bits_per_pixel){ + case 8: + case 16: + break; + case 32: + if(share->revid == (unsigned char)SM750LE_REVISION_ID){ + pr_debug("750le do not support 32bpp\n"); + return -EINVAL; + } + break; + default: + return -EINVAL; + + } + + return 0; +} + + +/* + set the controller's mode for @crtc charged with @var and @fix parameters +*/ +int hw_sm750_crtc_setMode(struct lynxfb_crtc* crtc, + struct fb_var_screeninfo* var, + struct fb_fix_screeninfo* fix) +{ + int ret,fmt; + u32 reg; + mode_parameter_t modparm; + clock_type_t clock; + struct lynx_share * share; + struct lynxfb_par * par; + + + ret = 0; + par = container_of(crtc,struct lynxfb_par,crtc); + share = par->share; +#if 1 + if(!share->accel_off){ + /* set 2d engine pixel format according to mode bpp */ + switch(var->bits_per_pixel){ + case 8: + fmt = 0; + break; + case 16: + fmt = 1; + break; + case 32: + default: + fmt = 2; + break; + } + hw_set2dformat(&share->accel,fmt); + } +#endif + + /* set timing */ +// modparm.pixel_clock = PS_TO_HZ(var->pixclock); + modparm.pixel_clock = ps_to_hz(var->pixclock); + modparm.vertical_sync_polarity = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? POS:NEG; + modparm.horizontal_sync_polarity = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? POS:NEG; + modparm.clock_phase_polarity = (var->sync& FB_SYNC_COMP_HIGH_ACT) ? POS:NEG; + modparm.horizontal_display_end = var->xres; + modparm.horizontal_sync_width = var->hsync_len; + modparm.horizontal_sync_start = var->xres + var->right_margin; + modparm.horizontal_total = var->xres + var->left_margin + var->right_margin + var->hsync_len; + modparm.vertical_display_end = var->yres; + modparm.vertical_sync_height = var->vsync_len; + modparm.vertical_sync_start = var->yres + var->lower_margin; + modparm.vertical_total = var->yres + var->upper_margin + var->lower_margin + var->vsync_len; + + /* choose pll */ + if(crtc->channel != sm750_secondary) + clock = PRIMARY_PLL; + else + clock = SECONDARY_PLL; + + pr_debug("Request pixel clock = %lu\n",modparm.pixel_clock); + ret = ddk750_setModeTiming(&modparm,clock); + if(ret){ + pr_err("Set mode timing failed\n"); + goto exit; + } + + if(crtc->channel != sm750_secondary){ + /* set pitch, offset ,width,start address ,etc... */ + POKE32(PANEL_FB_ADDRESS, + FIELD_SET(0,PANEL_FB_ADDRESS,STATUS,CURRENT)| + FIELD_SET(0,PANEL_FB_ADDRESS,EXT,LOCAL)| + FIELD_VALUE(0,PANEL_FB_ADDRESS,ADDRESS,crtc->oScreen)); + + reg = var->xres * (var->bits_per_pixel >> 3); + /* crtc->channel is not equal to par->index on numeric,be aware of that */ + reg = PADDING(crtc->line_pad,reg); + + POKE32(PANEL_FB_WIDTH, + FIELD_VALUE(0,PANEL_FB_WIDTH,WIDTH,reg)| + FIELD_VALUE(0,PANEL_FB_WIDTH,OFFSET,fix->line_length)); + + POKE32(PANEL_WINDOW_WIDTH, + FIELD_VALUE(0,PANEL_WINDOW_WIDTH,WIDTH,var->xres -1)| + FIELD_VALUE(0,PANEL_WINDOW_WIDTH,X,var->xoffset)); + + POKE32(PANEL_WINDOW_HEIGHT, + FIELD_VALUE(0,PANEL_WINDOW_HEIGHT,HEIGHT,var->yres_virtual - 1)| + FIELD_VALUE(0,PANEL_WINDOW_HEIGHT,Y,var->yoffset)); + + POKE32(PANEL_PLANE_TL,0); + + POKE32(PANEL_PLANE_BR, + FIELD_VALUE(0,PANEL_PLANE_BR,BOTTOM,var->yres - 1)| + FIELD_VALUE(0,PANEL_PLANE_BR,RIGHT,var->xres - 1)); + + /* set pixel format */ + reg = PEEK32(PANEL_DISPLAY_CTRL); + POKE32(PANEL_DISPLAY_CTRL, + FIELD_VALUE(reg, + PANEL_DISPLAY_CTRL,FORMAT, + (var->bits_per_pixel >> 4) + )); + }else{ + /* not implemented now */ + POKE32(CRT_FB_ADDRESS,crtc->oScreen); + reg = var->xres * (var->bits_per_pixel >> 3); + /* crtc->channel is not equal to par->index on numeric,be aware of that */ + reg = PADDING(crtc->line_pad,reg); + + POKE32(CRT_FB_WIDTH, + FIELD_VALUE(0,CRT_FB_WIDTH,WIDTH,reg)| + FIELD_VALUE(0,CRT_FB_WIDTH,OFFSET,fix->line_length)); + + /* SET PIXEL FORMAT */ + reg = PEEK32(CRT_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,CRT_DISPLAY_CTRL,FORMAT,var->bits_per_pixel >> 4); + POKE32(CRT_DISPLAY_CTRL,reg); + + } + + +exit: + return ret; +} + +void hw_sm750_crtc_clear(struct lynxfb_crtc* crtc) +{ + + return; +} + +int hw_sm750_setColReg(struct lynxfb_crtc* crtc,ushort index, + ushort red,ushort green,ushort blue) +{ + static unsigned int add[]={PANEL_PALETTE_RAM,CRT_PALETTE_RAM}; + POKE32(add[crtc->channel] + index*4 ,(red<<16)|(green<<8)|blue); + return 0; +} + +int hw_sm750le_setBLANK(struct lynxfb_output * output,int blank){ + int dpms,crtdb; + + switch(blank) + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_UNBLANK: +#else + case VESA_NO_BLANKING: +#endif + dpms = CRT_DISPLAY_CTRL_DPMS_0; + crtdb = CRT_DISPLAY_CTRL_BLANK_OFF; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_NORMAL: + dpms = CRT_DISPLAY_CTRL_DPMS_0; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_VSYNC_SUSPEND: +#else + case VESA_VSYNC_SUSPEND: +#endif + dpms = CRT_DISPLAY_CTRL_DPMS_2; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_HSYNC_SUSPEND: +#else + case VESA_HSYNC_SUSPEND: +#endif + dpms = CRT_DISPLAY_CTRL_DPMS_1; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_POWERDOWN: +#else + case VESA_POWERDOWN: +#endif + dpms = CRT_DISPLAY_CTRL_DPMS_3; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; + } + + if(output->paths & sm750_crt){ + POKE32(CRT_DISPLAY_CTRL,FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL),CRT_DISPLAY_CTRL,DPMS,dpms)); + POKE32(CRT_DISPLAY_CTRL,FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL),CRT_DISPLAY_CTRL,BLANK,crtdb)); + } + return 0; +} + +int hw_sm750_setBLANK(struct lynxfb_output* output,int blank) +{ + unsigned int dpms,pps,crtdb; + + dpms = pps = crtdb = 0; + + switch (blank) + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_UNBLANK: +#else + case VESA_NO_BLANKING: +#endif + pr_info("flag = FB_BLANK_UNBLANK \n"); + dpms = SYSTEM_CTRL_DPMS_VPHP; + pps = PANEL_DISPLAY_CTRL_DATA_ENABLE; + crtdb = CRT_DISPLAY_CTRL_BLANK_OFF; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_NORMAL: + pr_info("flag = FB_BLANK_NORMAL \n"); + dpms = SYSTEM_CTRL_DPMS_VPHP; + pps = PANEL_DISPLAY_CTRL_DATA_DISABLE; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_VSYNC_SUSPEND: +#else + case VESA_VSYNC_SUSPEND: +#endif + dpms = SYSTEM_CTRL_DPMS_VNHP; + pps = PANEL_DISPLAY_CTRL_DATA_DISABLE; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_HSYNC_SUSPEND: +#else + case VESA_HSYNC_SUSPEND: +#endif + dpms = SYSTEM_CTRL_DPMS_VPHN; + pps = PANEL_DISPLAY_CTRL_DATA_DISABLE; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_POWERDOWN: +#else + case VESA_POWERDOWN: +#endif + dpms = SYSTEM_CTRL_DPMS_VNHN; + pps = PANEL_DISPLAY_CTRL_DATA_DISABLE; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; + } + + if(output->paths & sm750_crt){ + + POKE32(SYSTEM_CTRL,FIELD_VALUE(PEEK32(SYSTEM_CTRL),SYSTEM_CTRL,DPMS,dpms)); + POKE32(CRT_DISPLAY_CTRL,FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL),CRT_DISPLAY_CTRL,BLANK,crtdb)); + } + + if(output->paths & sm750_panel){ + POKE32(PANEL_DISPLAY_CTRL,FIELD_VALUE(PEEK32(PANEL_DISPLAY_CTRL),PANEL_DISPLAY_CTRL,DATA,pps)); + } + + return 0; +} + + +void hw_sm750_initAccel(struct lynx_share * share) +{ + u32 reg; + enable2DEngine(1); + + if(getChipType() == SM750LE){ + reg = PEEK32(DE_STATE1); + reg = FIELD_SET(reg,DE_STATE1,DE_ABORT,ON); + POKE32(DE_STATE1,reg); + + reg = PEEK32(DE_STATE1); + reg = FIELD_SET(reg,DE_STATE1,DE_ABORT,OFF); + POKE32(DE_STATE1,reg); + + }else{ + /* engine reset */ + reg = PEEK32(SYSTEM_CTRL); + reg = FIELD_SET(reg,SYSTEM_CTRL,DE_ABORT,ON); + POKE32(SYSTEM_CTRL,reg); + + reg = PEEK32(SYSTEM_CTRL); + reg = FIELD_SET(reg,SYSTEM_CTRL,DE_ABORT,OFF); + POKE32(SYSTEM_CTRL,reg); + } + + /* call 2d init */ + share->accel.de_init(&share->accel); +} + +int hw_sm750le_deWait() +{ + int i=0x10000000; + while(i--){ + unsigned int dwVal = PEEK32(DE_STATE2); + if((FIELD_GET(dwVal,DE_STATE2,DE_STATUS) == DE_STATE2_DE_STATUS_IDLE) && + (FIELD_GET(dwVal,DE_STATE2,DE_FIFO) == DE_STATE2_DE_FIFO_EMPTY) && + (FIELD_GET(dwVal,DE_STATE2,DE_MEM_FIFO) == DE_STATE2_DE_MEM_FIFO_EMPTY)) + { + return 0; + } + } + /* timeout error */ + return -1; +} + + +int hw_sm750_deWait() +{ + int i=0x10000000; + while(i--){ + unsigned int dwVal = PEEK32(SYSTEM_CTRL); + if((FIELD_GET(dwVal,SYSTEM_CTRL,DE_STATUS) == SYSTEM_CTRL_DE_STATUS_IDLE) && + (FIELD_GET(dwVal,SYSTEM_CTRL,DE_FIFO) == SYSTEM_CTRL_DE_FIFO_EMPTY) && + (FIELD_GET(dwVal,SYSTEM_CTRL,DE_MEM_FIFO) == SYSTEM_CTRL_DE_MEM_FIFO_EMPTY)) + { + return 0; + } + } + /* timeout error */ + return -1; +} + +int hw_sm750_pan_display(struct lynxfb_crtc *crtc, + const struct fb_var_screeninfo *var, + const struct fb_info *info) +{ + uint32_t total; + //check params + if ((var->xoffset + var->xres > var->xres_virtual) || + (var->yoffset + var->yres > var->yres_virtual)) { + return -EINVAL; + } + + total = var->yoffset * info->fix.line_length + + ((var->xoffset * var->bits_per_pixel) >> 3); + total += crtc->oScreen; + if (crtc->channel == sm750_primary) { + POKE32(PANEL_FB_ADDRESS, + FIELD_VALUE(PEEK32(PANEL_FB_ADDRESS), + PANEL_FB_ADDRESS, ADDRESS, total)); + } else { + POKE32(CRT_FB_ADDRESS, + FIELD_VALUE(PEEK32(CRT_FB_ADDRESS), + CRT_FB_ADDRESS, ADDRESS, total)); + } + return 0; +} + diff --git a/drivers/staging/sm750fb/sm750_hw.h b/drivers/staging/sm750fb/sm750_hw.h new file mode 100644 index 000000000000..b05be5e99f51 --- /dev/null +++ b/drivers/staging/sm750fb/sm750_hw.h @@ -0,0 +1,104 @@ +#ifndef LYNX_HW750_H__ +#define LYNX_HW750_H__ + + +#define DEFAULT_SM750_CHIP_CLOCK 290 +#define DEFAULT_SM750LE_CHIP_CLOCK 333 +#ifndef SM750LE_REVISION_ID +#define SM750LE_REVISION_ID (unsigned char)0xfe +#endif + +//#define DEFAULT_MEM_CLOCK (DEFAULT_SM750_CHIP_CLOCK/1) +//#define DEFAULT_MASTER_CLOCK (DEFAULT_SM750_CHIP_CLOCK/3) + + +enum sm750_pnltype{ + + sm750_24TFT = 0,/* 24bit tft */ + + sm750_dualTFT = 2,/* dual 18 bit tft */ + + sm750_doubleTFT = 1,/* 36 bit double pixel tft */ +}; + +/* vga channel is not concerned */ +enum sm750_dataflow{ + sm750_simul_pri,/* primary => all head */ + + sm750_simul_sec,/* secondary => all head */ + + sm750_dual_normal,/* primary => panel head and secondary => crt */ + + sm750_dual_swap,/* primary => crt head and secondary => panel */ +}; + + +enum sm750_channel{ + sm750_primary = 0, + /* enum value equal to the register filed data */ + sm750_secondary = 1, +}; + +enum sm750_path{ + sm750_panel = 1, + sm750_crt = 2, + sm750_pnc = 3,/* panel and crt */ +}; + +struct init_status{ + ushort powerMode; + /* below three clocks are in unit of MHZ*/ + ushort chip_clk; + ushort mem_clk; + ushort master_clk; + ushort setAllEngOff; + ushort resetMemory; +}; + +struct sm750_state{ + struct init_status initParm; + enum sm750_pnltype pnltype; + enum sm750_dataflow dataflow; + int nocrt; + int xLCD; + int yLCD; +}; + +/* sm750_share stands for a presentation of two frame buffer + that use one sm750 adaptor, it is similiar to the super class of lynx_share + in C++ +*/ + +struct sm750_share{ + /* it's better to put lynx_share struct to the first place of sm750_share */ + struct lynx_share share; + struct sm750_state state; + int hwCursor; + /* 0: no hardware cursor + 1: primary crtc hw cursor enabled, + 2: secondary crtc hw cursor enabled + 3: both ctrc hw cursor enabled + */ +}; + +int hw_sm750_map(struct lynx_share* share,struct pci_dev* pdev); +int hw_sm750_inithw(struct lynx_share*,struct pci_dev *); +void hw_sm750_initAccel(struct lynx_share *); +int hw_sm750_deWait(void); +int hw_sm750le_deWait(void); + +resource_size_t hw_sm750_getVMSize(struct lynx_share *); +int hw_sm750_output_checkMode(struct lynxfb_output*,struct fb_var_screeninfo*); +int hw_sm750_output_setMode(struct lynxfb_output*,struct fb_var_screeninfo*,struct fb_fix_screeninfo*); +int hw_sm750_crtc_checkMode(struct lynxfb_crtc*,struct fb_var_screeninfo*); +int hw_sm750_crtc_setMode(struct lynxfb_crtc*,struct fb_var_screeninfo*,struct fb_fix_screeninfo*); +int hw_sm750_setColReg(struct lynxfb_crtc*,ushort,ushort,ushort,ushort); +int hw_sm750_setBLANK(struct lynxfb_output*,int); +int hw_sm750le_setBLANK(struct lynxfb_output*,int); +void hw_sm750_crtc_clear(struct lynxfb_crtc*); +void hw_sm750_output_clear(struct lynxfb_output*); +int hw_sm750_pan_display(struct lynxfb_crtc *crtc, + const struct fb_var_screeninfo *var, + const struct fb_info *info); + +#endif -- 2.20.1