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 <sudip@vectorindia.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Sudip Mukherjee
2015-03-06 16:37:31 -08:00
committed by Greg Kroah-Hartman
parent c3d6047d95
commit 81dee67e21
36 changed files with 9962 additions and 0 deletions
+2
View File
@@ -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"
+1
View File
@@ -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/
+10
View File
@@ -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 <file:Documentation/kbuild/modules.txt>.
+4
View File
@@ -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
+15
View File
@@ -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 <greg@kroah.com>
Sudip Mukherjee <sudipm.mukherjee@gmail.com>
Teddy Wang <teddy.wang@siliconmotion.com>
Sudip Mukherjee <sudip@vectorindia.org>
+24
View File
@@ -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
File diff suppressed because it is too large Load Diff
+83
View File
@@ -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
+318
View File
@@ -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;
}
+160
View File
@@ -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
+99
View File
@@ -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
+67
View File
@@ -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
+19
View File
@@ -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");
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef DDK750_HELP_H__
#define DDK750_HELP_H__
#include "ddk750_chip.h"
#ifndef USE_INTERNAL_REGISTER_ACCESS
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#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
+271
View File
@@ -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, &registerIndex) == 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
+10
View File
@@ -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
+205
View File
@@ -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;
}
+43
View File
@@ -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
+239
View File
@@ -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);
}
+71
View File
@@ -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

Some files were not shown because too many files have changed in this diff Show More