📄 sed135x.c
字号:
//==========================================================================
//
// sed135x.c
//
// Author(s): Michael Kelly - Cogent Computer Systems, Inc.
// Date: 05-24-2002
// Description: Init Code for SED135x Display Controller
//
//==========================================================================
#include "config.h"
#include "cpuio.h"
#include "genlib.h"
#include "stddefs.h"
#include "sed1355.h"
#include "sed1356.h"
#include "font8x16.h"
#include "sed_lut.h"
//--------------------------------------------------------------------------
// function prototypes
//
ulong sed135x_init(void);
void sed135x_on(void);
void sed135x_off(void);
void sed_lcd_bkl(uchar bright);
void sed_putchar(char c);
void sed_writechar(uchar c);
void sed_clr_row(int char_row);
int sed_tst(int argc,char *argv[]);
int sed(int argc,char *argv[]);
extern int udelay(int delay);
extern lcd_bkl(uchar bright);
extern lcd_bkl(uchar bright);
extern void fs6377_init(int);
extern ulong i2c_rd_device(uchar dev, uchar reg, uchar *data);
// global flags to determine what, if anything, was found
int sed135x_ok;
int sed135x_tst = 0; // flag to indicate we are testing to disable sed_puchar
int sed1355;
int sed_disp_mode_crt;
// globals to keep track of foreground, background colors and x,y position
int sed_color_depth; // 4, 8 or 16
int sed_fg_color; // 0 to 15, used as lookup into VGA color table
int sed_bg_color; // 0 to 15, used as lookup into VGA color table
int sed_col; // current column, 0 to COLS_PER_SCREEN - 1
int sed_row; // current row, 0 to (ROWS_PER_SCREEN * 2) - 1
ulong sed_fb_offset; // current offset into frame buffer for sed_putchar
// GPIO1 is used to control the LCD backlight on many CSB's
#define SED1355_BKL_ON SED1355_REG_GPIO_CTL0 |= SED1355_GPIO_GPIO1 // GPIO1 = 1
#define SED1355_BKL_OFF SED1355_REG_GPIO_CTL0 &= ~SED1355_GPIO_GPIO1 // GPIO1 = 0
#define SED1356_BKL_ON SED1356_REG_GPIO_CTL |= SED1356_GPIO_GPIO1 // GPIO1 = 1
#define SED1356_BKL_OFF SED1356_REG_GPIO_CTL &= ~SED1356_GPIO_GPIO1 // GPIO1 = 0
// GPIO2 is used to sense the presence of a monitor. 0 = monitor connected, 1 = no monitor
// we invert the sense to make it easier to test and more logical.
#define SED1355_CRT SED1355_REG_GPIO_CTL0 & SED1355_GPIO_GPIO2
#define SED1356_CRT SED1356_REG_GPIO_CTL & SED1356_GPIO_GPIO2
#define SED_FB_SIZE(_depth_) (((PIXELS_PER_COL * PIXELS_PER_ROW) * _depth_) / 8)
#define SED_ROW_SIZE(_depth_) ((PIXELS_PER_ROW * _depth_) / 8)
#define SED_GET_ADD(_row_, _col_, _depth_) (((((_row_ * PIXELS_PER_ROW) * FONT_HEIGHT) \
+ (_col_ * FONT_WIDTH)) \
* _depth_) / 8)
//--------------------------------------------------------------------------
// sed135x_on
//
// This function turns on the SED1355 or SED1356 LCD and/or CRT
//
void sed135x_on()
{
uchar temp8;
int i;
sed135x_off();
// Turn on the LCD and/or CRT
if (sed1355){
// The SED1355 has only one set of timing registers so we need
// re-write them with the correct mode each time we get called.
if (sed_disp_mode_crt) { // 1 = CRT Mode
// turn off the display fifo first
SED1355_REG_PERF_HI |= SED1355_PERF_HI_DFH;
// turn the LCD backlight off
lcd_bkl(0);
// Change the timing to CRT Mode
SED1355_REG_HOR_PULSE = SED1355_PULSE_WID(SED_HOR_PULSE_WIDTH_CRT) | SED1355_PULSE_LCD_POL_LO;
SED1355_REG_HOR_START = SED_HOR_PULSE_START_CRT;
SED1355_REG_HOR_NONDISP = SED_HOR_NONDISP_CRT;
SED1355_REG_VER_PULSE = SED1355_PULSE_WID(SED_VER_PULSE_WIDTH_CRT) | SED1355_PULSE_LCD_POL_LO;
SED1355_REG_VER_START = SED_VER_PULSE_START_CRT;
SED1355_REG_VER_NONDISP = SED_VER_NONDISP_CRT;
SED1355_REG_DISP_MODE = SED1355_DISP_MODE_CRT;
// now we can turn the display fifo on
SED1355_REG_PERF_HI &= ~SED1355_PERF_HI_DFH;
} // if CRT Mode
else { // 0 = LCD Mode
// turn off the display fifo first
SED1355_REG_PERF_HI |= SED1355_PERF_HI_DFH;
// Change the timing to LCD Mode
SED1355_REG_HOR_PULSE = SED1355_PULSE_WID(SED_HOR_PULSE_WIDTH_LCD) | SED1355_PULSE_LCD_POL_LO;
SED1355_REG_HOR_START = SED_HOR_PULSE_START_LCD;
SED1355_REG_HOR_NONDISP = SED_HOR_NONDISP_LCD;
SED1355_REG_VER_PULSE = SED1355_PULSE_WID(SED_VER_PULSE_WIDTH_LCD) | SED1355_PULSE_LCD_POL_LO;
SED1355_REG_VER_START = SED_VER_PULSE_START_LCD;
SED1355_REG_VER_NONDISP = SED_VER_NONDISP_LCD;
SED1355_REG_DISP_MODE = SED1355_DISP_MODE_LCD;
// now we can turn the display fifo on
lcd_bkl(0xff);
} // else LCD Mode
} // if SED1355
else {
// The SED1356 supports seperate LCD and CRT timing registers
// that have already been setup. We just blank the side we
// aren't using and enable the other.
if (sed_disp_mode_crt) { // 1 = CRT Mode
// Blank the LCD and CRT
SED1356_REG_LCD_DISP_MODE |= SED1356_LCD_DISP_BLANK;
SED1356_REG_CRT_DISP_MODE |= SED1356_CRT_DISP_BLANK;
// turn the LCD backlight off
lcd_bkl(0);
// Set the SED1356 to CRT Mode
SED1356_REG_DISP_MODE = SED1356_DISP_SWIV_NORM | SED1356_DISP_MODE_CRT;
// Turn on the CRT
SED1356_REG_CRT_DISP_MODE &= ~SED1356_CRT_DISP_BLANK;
} // if CRT mode
else { // 0 = LCD Mode
// Blank the LCD and CRT
SED1356_REG_LCD_DISP_MODE |= SED1356_LCD_DISP_BLANK;
SED1356_REG_CRT_DISP_MODE |= SED1356_CRT_DISP_BLANK;
// Set the SED1356 to LCD Mode
SED1356_REG_DISP_MODE = SED1356_DISP_SWIV_NORM | SED1356_DISP_MODE_LCD;
// Turn on the LCD
SED1356_REG_LCD_DISP_MODE &= ~SED1356_LCD_DISP_BLANK;
lcd_bkl(0xff); // turn the LCD backlight on/full brightness
} // else LCD Mode
} // else SED1356
udelay(10000); // wait for Power-up sequence to complete
}
//--------------------------------------------------------------------------
// sed_lcd_bkl()
//
// This function turns on the LCD backlight connected to GPIO1. This is
// not used if the board has a different method of controlling the
// backlight. Since the Sed has only a single GPIO bit and no way
// to modulate it, we use any non-zero value of bright to turn it on.
//
void sed_lcd_bkl(uchar bright)
{
// Any non-zero value for bright means on
if (sed1355){
if (bright) SED1355_BKL_ON;
else SED1355_BKL_OFF;
}
else { // SED1356
if (bright) SED1356_BKL_ON;
else SED1356_BKL_OFF;
}
}
//--------------------------------------------------------------------------
// sed135x_off
//
// This function turns off the SED1355 LCD and/or CRT and the display
// fifo. It can also turn off the clocks if mode is true, thus allowing
// the programmable clock generator to be changed.
//
void sed135x_off()
{
if (sed1355) SED1355_REG_DISP_MODE = 0x00;
else SED1356_REG_DISP_MODE = SED1356_DISP_SWIV_NORM | SED1356_DISP_MODE_OFF;
lcd_bkl(0); // turn the LCD backlight off
}
//--------------------------------------------------------------------------
// sed135x_init
//
// This function sets up the sed1355 or sed1356 whichever is found
//
vulong sed135x_init()
{
vushort temp16;
int i;
sed135x_ok = 0;
sed1355 = 0;
sed_disp_mode_crt = 0; // assume LCD
// Check the ID to make sure we even have a SED1355 or 1356 installed
temp16 = SED_REG_REV & SED_REV_ID_MASK;
if ((temp16 != SED_REV_ID_1355) && (temp16 != SED_REV_ID_1356)){
printf("SED135x Not Found! SED_REG_REV = %04x.\n", temp16);
return -1;
}
if (temp16 == SED_REV_ID_1355)
{
sed1355 = 1;
// Enable Host Access
SED1355_REG_MISC = 0x00;
// Disable the display FIFO to stop all display accesses
SED1355_REG_PERF_HI |= SED1355_PERF_HI_DFH;
// Test for the presence of a CRT
SED1355_REG_GPIO_CTL0 = 0x00; // clear all GPIO's
SED1355_REG_GPIO_CFG0 = SED1355_GPIO_GPIO1; // set GPIO1 as output, GPIO2 as input
if (SED1355_CRT == 0) sed_disp_mode_crt = 1;
// Enable Power Save Mode before we mess with the clocks
SED1355_REG_PWR_CFG |= SED1355_PWR_CFG_SUSP_SR | SED1355_PWR_CFG_LCD_PWR | SED1355_PWR_CFG_SW_SUSP;
// Wait until power is down
while ((SED1355_REG_PWR_CFG & SED1355_PWR_CFG_STAT) == 0){}
// Change the programmable clock generator to the desired timing
if (sed_disp_mode_crt) fs6377_init(SED_DISP_MODE_CRT);
else fs6377_init(SED_DISP_MODE_LCD);
// Re-enable Power
SED1355_REG_PWR_CFG = 0x00;
// Write the registers that are common to both modes
// LCD and CRT specific timing will be written when the
// display is turned on.
SED1355_REG_MEM_CFG = SED1355_MEM_CFG_REF_2048 | SED1355_MEM_CFG_TYPE_EDO | SED1355_MEM_CFG_CAS_CTL;
SED1355_REG_PANEL_TYPE = SED1355_PANEL_TYPE_16 | SED1355_PANEL_TYPE_CLR | SED1355_PANEL_TYPE_TFT;
SED1355_REG_HOR_DISP = (PIXELS_PER_ROW/8) - 1;
SED1355_REG_VER_DISP_HT_LO = (PIXELS_PER_COL - 1) & 0x0ff;
SED1355_REG_VER_DISP_HT_HI = ((PIXELS_PER_COL - 1) & 0x300) >> 8;
SED1355_REG_LINE_COMP0 = 0xFF; // 1 screen so set the split point to the max - 1024
SED1355_REG_LINE_COMP1 = 0x03;
SED1355_REG_MADD_OFF_LO = PIXELS_PER_ROW & 0x0ff;
SED1355_REG_MADD_OFF_HI = (PIXELS_PER_ROW & 0x300) >> 8;
SED1355_REG_PERF_LO = SED1355_PERF_LO_NRC_3 | SED1355_PERF_LO_RCD_1 | SED1355_PERF_LO_NRP_1;
// The following registers are all intialized to 0
SED1355_REG_DISP1_START_LO = 0x00;
SED1355_REG_DISP1_START_MID = 0x00;
SED1355_REG_DISP1_START_HI = 0x00;
SED1355_REG_DISP2_START_LO = 0x00;
SED1355_REG_DISP2_START_MID = 0x00;
SED1355_REG_DISP2_START_HI = 0x00;
SED1355_REG_PIXEL_PAN = 0x00;
SED1355_REG_CLK_CFG = 0x00; // PCLK = MCLK
SED1355_REG_PWR_CFG = 0x00;
SED1355_REG_GPIO_CFG1 = 0x00;
SED1355_REG_GPIO_CTL1 = 0x00;
SED1355_REG_LUT_ADD = 0x00;
SED1355_REG_LUT_DAT = 0x00;
SED1355_REG_CRSR_CTL = 0x00;
SED1355_REG_CRSR_X_LO = 0x00;
SED1355_REG_CRSR_X_HI = 0x00;
SED1355_REG_CRSR_Y_LO = 0x00;
SED1355_REG_CRSR_Y_HI = 0x00;
SED1355_REG_CRSR_CLR0_LO = 0x00;
SED1355_REG_CRSR_CLR0_HI = 0x00;
SED1355_REG_CRSR_CLR1_LO = 0x00;
SED1355_REG_CRSR_CLR1_HI = 0x00;
SED1355_REG_CRSR_START = 0x00;
SED1355_REG_ALT_FRM = 0x00;
// Test for the presence of a CRT
if (SED1355_CRT == 0) sed_disp_mode_crt = 1;
} // if sed1355
else {
// Enable Host Access
SED1356_REG_MISC = 0x00;
// Disable the display
SED1356_REG_DISP_MODE = SED1356_DISP_SWIV_NORM | SED1356_DISP_MODE_OFF;
// Test for the presence of a CRT
SED1356_REG_GPIO_CTL = 0x00; // Disable Backlight
SED1356_REG_GPIO_CFG = SED1356_GPIO_GPIO1; // GPIO1 Out, GPIO2 In
if (SED1356_CRT) sed_disp_mode_crt = 0;
else sed_disp_mode_crt = 1;
// Enable Power Save Mode before we mess with the clocks
SED1356_REG_REF_RATE |= SED1356_REF_TYPE_SELF; // set dram to self refresh first
SED1356_REG_PWR_CFG |= SED1356_PWR_MCLK;
// Wait until power is down
while ((SED1356_REG_PWR_STAT & SED1356_PWR_MCLK) == 0){}
// Change the programmable clock generator to the desired timing
if (sed_disp_mode_crt) fs6377_init(SED_DISP_MODE_CRT);
else fs6377_init(SED_DISP_MODE_LCD);
// Re-enable Power
SED1356_REG_PWR_CFG = 0x00;
// Common Control Registers
SED1356_REG_MCLK_CFG = SED1356_MCLK_SRC_BCLK;
SED1356_REG_LCD_PCLK_CFG = SED1356_PCLK_SRC_CLKI;
SED1356_REG_CRT_PCLK_CFG = SED1356_PCLK_SRC_CLKI;
SED1356_REG_MEDIA_PCLK_CFG = 0x00;
SED1356_REG_WAIT_STATE = 0x01;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -