📄 sed135x_16bit.c
字号:
extern void fs6377_init(int);
// Why doesn't the real mode work?
#define fs6377_init(mode) _csb281_fs6377_init(0)
// global flags to determine what, if anything, was found
static int sed135x_ok;
static int sed_disp_mode_crt;
// GPIO1 is used to control the LCD backlight on many CSB's
#define SED1356_BKL_ON SED1356_REG_GPIO_CTL |= H2SED(SED1356_GPIO_GPIO1) // GPIO1 = 1
#define SED1356_BKL_OFF SED1356_REG_GPIO_CTL &= H2SED(~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 SED1356_CRT SED1356_REG_GPIO_CTL & H2SED(SED1356_GPIO_GPIO2)
#define SED_ROW_SIZE(_depth_) ((PIXELS_PER_ROW * _depth_) / 8)
//--------------------------------------------------------------------------
// sed135x_on
//
// This function turns on the SED1355 or SED1356 LCD and/or CRT
//
static void
sed135x_on(void)
{
uchar temp8;
int i;
sed135x_off();
// Turn on the LCD and/or CRT
// 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_and_MISC |= H2SED(SED1356_LCD_DISP_BLANK);
SED1356_REG_CRT_DISP_MODE |= H2SED(SED1356_CRT_DISP_BLANK);
// turn the LCD backlight off
sed_lcd_bkl(0);
// Set the SED1356 to CRT Mode
SED1356_REG_DISP_MODE = H2SED(SED1356_DISP_SWIV_NORM |
SED1356_DISP_MODE_CRT);
// Turn on the CRT
SED1356_REG_CRT_DISP_MODE &= ~H2SED(SED1356_CRT_DISP_BLANK);
} // if CRT mode
else { // 0 = LCD Mode
// Blank the LCD and CRT
SED1356_REG_LCD_DISP_MODE_and_MISC |= H2SED(SED1356_LCD_DISP_BLANK);
SED1356_REG_CRT_DISP_MODE |= H2SED(SED1356_CRT_DISP_BLANK);
// Set the SED1356 to LCD Mode
SED1356_REG_DISP_MODE = H2SED(SED1356_DISP_SWIV_NORM |
SED1356_DISP_MODE_LCD);
// Turn on the LCD
SED1356_REG_LCD_DISP_MODE_and_MISC &= ~H2SED(SED1356_LCD_DISP_BLANK);
sed_lcd_bkl(0xff); // turn the LCD backlight on/full brightness
} // else LCD Mode
}
//--------------------------------------------------------------------------
// 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.
//
static void
sed_lcd_bkl(uchar bright)
{
// Any non-zero value for bright means on
if (bright)
SED1356_BKL_ON;
else
SED1356_BKL_OFF;
}
//--------------------------------------------------------------------------
// sed135x_off
//
// This function turns off the SED1356 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.
//
static void
sed135x_off(void)
{
SED1356_REG_DISP_MODE = H2SED(SED1356_DISP_SWIV_NORM |
SED1356_DISP_MODE_OFF);
sed_lcd_bkl(0); // turn the LCD backlight off
}
//--------------------------------------------------------------------------
// sed135x_init
//
// This function sets up the sed1355 or sed1356 whichever is found
//
int
sed135x_init(int depth, struct lcd_info *lcd)
{
vushort temp16;
int i;
sed135x_ok = 0;
sed_disp_mode_crt = 0; // assume LCD
if ((depth != 4) && (depth != 8) && (depth != 16)) {
diag_printf("Invalid depth: %d\n", depth);
return -1;
}
// enable host access
SED1356_REG_REV_and_MISC = 0x0000;
// Check the ID to make sure we even have a SED1356 installed
temp16 = SED1356_REG_REV_and_MISC & H2SED(SED1356_REV_ID_MASK);
if (temp16 != H2SED(SED1356_REV_ID_1356)){
diag_printf("SED1356 Not Found! SED_REG_REV = %04x.\n", temp16);
return -1;
}
// Disable the display
SED1356_REG_DISP_MODE = H2SED(SED1356_DISP_SWIV_NORM |
SED1356_DISP_MODE_OFF);
// Test for the presence of a CRT
SED1356_REG_GPIO_CTL = 0x0000; // Disable Backlight
SED1356_REG_GPIO_CFG = H2SED(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_MEM_CFG_and_REF_RATE = H2SED(SED1356_REF_TYPE_SELF); // set dram to self refresh first
// shut off MCLK
SED1356_REG_PWR_CFG_and_STAT = H2SED(SED1356_PWR_MCLK);
// Wait until power is down - when MCLK bit goes true
while ((SED1356_REG_PWR_CFG_and_STAT & H2SED(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_and_STAT = 0x0000;
// Common Control Registers
SED1356_REG_MCLK_CFG = H2SED(SED1356_MCLK_SRC_BCLK);
SED1356_REG_LCD_PCLK_CFG = H2SED(SED1356_PCLK_SRC_CLKI);
SED1356_REG_CRT_PCLK_CFG = H2SED(SED1356_PCLK_SRC_CLKI);
SED1356_REG_MEDIA_PCLK_CFG = 0x0000;
SED1356_REG_WAIT_STATE = H2SED(0x0001);
SED1356_REG_MEM_CFG_and_REF_RATE = H2SED(SED1356_MEM_CFG_2CAS_EDO |
SED1356_REF_RATE_2048);
SED1356_REG_MEM_TMG0_and_1 = H2SED(SED1356_MEM_TMG0_EDO50_MCLK33 |
SED1356_MEM_TMG1_EDO50_MCLK33);
SED1356_REG_PANEL_TYPE_and_MOD_RATE = H2SED(SED1356_PANEL_TYPE_16 |
SED1356_PANEL_TYPE_CLR |
SED1356_PANEL_TYPE_TFT);
// LCD Specific Registers
SED1356_REG_LCD_HOR_DISP = H2SED((PIXELS_PER_ROW/8) - 1);
SED1356_REG_LCD_HOR_NONDISP_and_START = H2SED(SED_HOR_NONDISP_LCD |
(SED_HOR_PULSE_START_LCD << 8));
SED1356_REG_LCD_HOR_PULSE = H2SED(SED1356_PULSE_WID(SED_HOR_PULSE_WIDTH_LCD) |
SED1356_PULSE_POL_LOW);
SED1356_REG_LCD_VER_DISP_HT_LO_and_HI = H2SED((PIXELS_PER_COL - 1) & 0x3ff);
SED1356_REG_LCD_VER_NONDISP_and_START = H2SED(SED_VER_NONDISP_LCD |
(SED_VER_PULSE_START_LCD << 8));
SED1356_REG_LCD_VER_PULSE = H2SED(SED1356_PULSE_WID(SED_VER_PULSE_WIDTH_LCD) |
SED1356_PULSE_POL_LOW);
switch (depth) {
case 4: SED1356_REG_LCD_DISP_MODE_and_MISC = H2SED(SED1356_LCD_DISP_BLANK |
SED1356_LCD_DISP_SWIV_NORM |
SED1356_LCD_DISP_4BPP);
break;
case 8: SED1356_REG_LCD_DISP_MODE_and_MISC = H2SED(SED1356_LCD_DISP_BLANK |
SED1356_LCD_DISP_SWIV_NORM |
SED1356_LCD_DISP_8BPP);
break;
default: SED1356_REG_LCD_DISP_MODE_and_MISC = H2SED(SED1356_LCD_DISP_BLANK |
SED1356_LCD_DISP_SWIV_NORM |
SED1356_LCD_DISP_16BPP); break;
}
SED1356_REG_LCD_DISP_START_LO_and_MID = 0x0000;
SED1356_REG_LCD_DISP_START_HI = 0x0000;
SED1356_REG_LCD_ADD_OFFSET_LO_and_HI = H2SED((SED_ROW_SIZE(depth) / 2) & 0x7ff);
SED1356_REG_LCD_PIXEL_PAN = 0x0000;
SED1356_REG_LCD_FIFO_THRESH_LO_and_HI = 0x0000; // auto mode
// LCD Specific Registers
SED1356_REG_CRT_HOR_DISP = H2SED((PIXELS_PER_ROW/8) - 1);
SED1356_REG_CRT_HOR_NONDISP_and_START = H2SED(SED_HOR_NONDISP_CRT |
(SED_HOR_PULSE_START_CRT << 8));
SED1356_REG_CRT_HOR_PULSE = H2SED(SED1356_PULSE_WID(SED_HOR_PULSE_WIDTH_CRT) |
SED1356_PULSE_POL_LOW);
SED1356_REG_CRT_VER_DISP_HT_LO_and_HI = H2SED((PIXELS_PER_COL - 1) & 0x3ff);
SED1356_REG_CRT_VER_NONDISP_and_START = H2SED(SED_VER_NONDISP_CRT |
(SED_VER_PULSE_START_CRT << 8));
SED1356_REG_CRT_VER_PULSE_and_OUT_CTL = H2SED(SED1356_PULSE_WID(SED_VER_PULSE_WIDTH_CRT) |
SED1356_PULSE_POL_LOW | SED1356_CRT_OUT_DAC_LVL);
switch (depth) {
case 4: SED1356_REG_CRT_DISP_MODE = H2SED(SED1356_CRT_DISP_BLANK |
SED1356_CRT_DISP_4BPP);
break;
case 8: SED1356_REG_CRT_DISP_MODE = H2SED(SED1356_CRT_DISP_BLANK |
SED1356_CRT_DISP_8BPP);
break;
default: SED1356_REG_CRT_DISP_MODE = H2SED(SED1356_CRT_DISP_BLANK |
SED1356_CRT_DISP_16BPP);
break;
}
SED1356_REG_CRT_DISP_START_LO_and_MID = 0x0000;
SED1356_REG_CRT_DISP_START_HI = 0x0000;
SED1356_REG_CRT_ADD_OFFSET_LO_and_HI = H2SED((SED_ROW_SIZE(depth) / 2) & 0x7ff);
SED1356_REG_CRT_PIXEL_PAN = 0x0000;
SED1356_REG_CRT_FIFO_THRESH_LO_and_HI = 0x0000; // auto mode
// Disable Cursor
SED1356_REG_LCD_CURSOR_CTL_and_START_ADD = 0x0000;
SED1356_REG_CRT_CURSOR_CTL_and_START_ADD = 0x0000;
// Disable BitBlt
SED1356_REG_BLT_CTL_0_and_1 = 0x0000;
SED1356_REG_BLT_ROP_CODE_and_BLT_OP = 0x0000;
SED1356_REG_BLT_SRC_START_LO_and_MID = 0x0000;
SED1356_REG_BLT_SRC_START_HI = 0x0000;
SED1356_REG_BLT_DEST_START_LO_and_MID = 0x0000;
SED1356_REG_BLT_DEST_START_HI = 0x0000;
SED1356_REG_BLT_ADD_OFFSET_LO_and_HI = 0x0000;
SED1356_REG_BLT_WID_LO_and_HI = 0x0000;
SED1356_REG_BLT_HGT_LO_and_HI = 0x0000;
SED1356_REG_BLT_BG_CLR_LO_and_HI = 0x0000;
SED1356_REG_BLT_FG_CLR_LO_and_HI = 0x0000;
// Fill the LUT, write to both LCD and CRT luts simultaneously
SED1356_REG_LUT_MODE = 0x0000;
for (i = 0; i < 256; i++){
SED1356_REG_LUT_ADD = H2SED(i);
SED1356_REG_LUT_DATA = H2SED(sed_lut_16bit[i][0]); // red
SED1356_REG_LUT_DATA = H2SED(sed_lut_16bit[i][1]); // green
SED1356_REG_LUT_DATA = H2SED(sed_lut_16bit[i][2]); // blue
}
// Disable Power Save Mode
SED1356_REG_PWR_CFG_and_STAT = 0x0000;
// Set Watchdog
// SED1356_REG_WATCHDOG_CTL = 0x0000;
// Device found & initialized
sed135x_ok = 1;
// turn on the display
sed135x_on();
// Fill in the info structure
lcd->height = 480; // FIXME
lcd->width = 640; // FIXME
lcd->bpp = depth;
lcd->type = FB_TRUE_RGB565;
lcd->rlen = (640*2*2); // FIXME
lcd->access_size = 2; // Framebuffer fixed at 16 bit access
lcd->stride = 4; // Only on "odd" 16 byte chunks
lcd->fb = SED_GET_PHYS_ADD(0);
lcd->on = sed135x_on;
lcd->off = sed135x_off;
return 0;
}
//--------------------------------------------------------------------------
// sed_pwr_dn()
static void
sed_pwr_dn(void)
{
// Enable Host Access
SED1356_REG_REV_and_MISC = 0x0000;
// Disable the display
SED1356_REG_DISP_MODE = H2SED(SED1356_DISP_MODE_OFF);
// Enable Power Save Mode
// set dram to self refresh first
SED1356_REG_MEM_CFG_and_REF_RATE = H2SED(SED1356_REF_TYPE_SELF);
// shut off MCLK
SED1356_REG_PWR_CFG_and_STAT = H2SED(SED1356_PWR_MCLK);
// Wait until power is down - when MCLK bit goes true
while ((SED1356_REG_PWR_CFG_and_STAT & H2SED(SED1356_PWR_MCLK)) == 0){}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -