📄 au1100_lcd.c
字号:
//==========================================================================
//
// au1100_lcd.c
//
// Author(s): Michael Kelly - Cogent Computer Systems, Inc.
// Date: 04/11/2003
// Description: Init Code for Au1100 LCD Controller
//
//==========================================================================
#include "config.h"
#include "cpuio.h"
#include "stddefs.h"
#include "genlib.h"
#include "au1100.h"
#include "au1100_lcd.h"
#include "font8x16.h"
#include "lcd_lut.h"
#define LCD_DBG
//--------------------------------------------------------------------------
// The LCD frame buffer is fixed at 0xa1000000, which is 1Mbyte from the
// beginning of SDRAM space. Note that we access it 16-bits at a time.
//
#define LCD_BUF_ADD 0xa1000000
#define LCD_BUF(_x_) *(vushort *)(LCD_BUF_ADD + _x_) // Frame Buffer
//--------------------------------------------------------------------------
// function prototypes and externs
//
int lcd_init(void);
void lcd_on(void);
void lcd_off(void);
void lcd_putchar(char c);
void lcd_writechar(uchar c);
void lcd_clr_row(int char_row);
extern void udelay(int);
// globals to keep track of foreground, background colors and x,y position
int lcd_color_depth; // 4, 8 or 16
int lcd_fg_color; // 0 to 15, used as lookup into VGA color table
int lcd_bg_color; // 0 to 15, used as lookup into VGA color table
int lcd_col; // current column, 0 to COLS_PER_SCREEN - 1
int lcd_row; // current row, 0 to (ROWS_PER_SCREEN * 2) - 1
int lcd_tst_mode = 0;
ulong lcd_fb_offset; // current offset into frame buffer for lcd_putchar
#define PIXELS_PER_ROW 640
#define PIXELS_PER_COL 480
#define ROWS_PER_SCREEN 30
#define COLS_PER_SCREEN 80
#define LCD_BG_DEF 1
#define LCD_FG_DEF 14
#define LCD_FB_SIZE(_depth_) (((PIXELS_PER_COL * PIXELS_PER_ROW) * _depth_) / 8)
#define LCD_ROW_SIZE(_depth_) ((PIXELS_PER_ROW * _depth_) / 8)
#define LCD_GET_ADD(_row_, _col_, _depth_) (((((_row_ * PIXELS_PER_ROW) * FONT_HEIGHT) \
+ (_col_ * FONT_WIDTH)) \
* _depth_) / 8)
//--------------------------------------------------------------------------
// lcd_init
//
// This function sets up the Au1100 LCD controller
//
int lcd_init()
{
ulong index;
int i;
ushort temp16;
#ifdef LCD_DBG
lcd_tst_mode = 1;
printf("Au1100 LCD Initialization.\n");
lcd_tst_mode = 0;
#endif
// Setup LCD Clock Generator for 96Mhz from Auxillary PLL
// This allows us to use a PCD = 1 which divides this
// by 4 for 24Mhz. We use the Auxillary PLL because it
// will always be set it to 96Mhz regardless of the CPU
// frequency
AU1100_SYS_REG(sys_clksrc) |= SYS_CLKSRC_ML(1); // direct from MUX
LCD_REG(LCD_CLK) = (LCD_CLK_PCD(1) // divide by 4
| LCD_CLK_FCLK_NEG // clock polarity
| LCD_CLK_LCLK_NEG
| LCD_CLK_PCLK_NEG
| LCD_CLK_BIAS_POS);
#ifdef LCD_DBG
lcd_tst_mode = 1;
printf("Au1100 LCD_CLK = 0x%08lx.\n", LCD_REG(LCD_CLK));
lcd_tst_mode = 0;
#endif
// set the PWM frequency to lowest possible
LCD_REG(LCD_PWMHI) = 0; // clear high time so always off
LCD_REG(LCD_PWMDIV) = LCD_PWMDIV_DIV(0xfff);
LCD_REG(LCD_PWMDIV) = LCD_PWMDIV_EN;
// Setup Timing Registers
// leave the go bit off for now. It will be enabled
// in the lcd enable function
LCD_REG(LCD_CTL) = (LCD_CTL_TFT // TFT Panel
| LCD_CTL_PO0 // Little Endian Pixel Ordering - All BPP settings
| LCD_CTL_TFT_D16 // 16-Bit Data Interface
| LCD_CTL_COH // mark LCD transfers as coherent
// | LCD_CTL_COLOR // Color display
| LCD_CTL_PPF_565); // RGB 565 ordering on pins
// set the bpp based on lcd_color_depth
switch (lcd_color_depth)
{
case 4:
LCD_REG(LCD_CTL) |= LCD_CTL_BPP4; // 4-bits/pixel
break;
case 8:
LCD_REG(LCD_CTL) |= LCD_CTL_BPP8; // 8-bits/pixel
break;
default:
LCD_REG(LCD_CTL) |= LCD_CTL_BPP16; // 16-bits/pixel
break;
} // switch color depth
#ifdef LCD_DBG
lcd_tst_mode = 1;
printf("Au1100 LCD_CTL = 0x%08lx.\n", LCD_REG(LCD_CTL));
lcd_tst_mode = 0;
#endif
LCD_REG(LCD_VER) = (LCD_VER_VN1(32) // Beginning-of-frame line clock wait count = VN1 + 1
| LCD_VER_VN2(32) // End-of-frame line clock wait count = VN2 + 1
| LCD_VER_VPW(1) // Vertical sync pulse width = VPW + 1
| LCD_VER_LPP((PIXELS_PER_COL - 1))); // Lines per panel = LPP + 1
#ifdef LCD_DBG
lcd_tst_mode = 1;
printf("Au1100 LCD_VER = 0x%08lx.\n", LCD_REG(LCD_VER));
lcd_tst_mode = 0;
#endif
LCD_REG(LCD_HOR) = (LCD_HOR_HN1(80) // Beginning-of-Line pixel clock Wait count = HN1 + 1
| LCD_HOR_HN2(80) // End-of-line pixel clock wait count = HN2 + 1
| LCD_HOR_HPW(2) // Horizontal sync pulse width = HPW + 1
| LCD_HOR_PPL((PIXELS_PER_ROW - 1))); // Pixels per line = PPL + 1
#ifdef LCD_DBG
lcd_tst_mode = 1;
printf("Au1100 LCD_HOR = 0x%08lx.\n", LCD_REG(LCD_HOR));
lcd_tst_mode = 0;
#endif
LCD_REG(LCD_WORDS) = (LCD_FB_SIZE(lcd_color_depth) / 2) - 1; // frame buffer size in 16-bit words
#ifdef LCD_DBG
lcd_tst_mode = 1;
printf("Au1100 LCD_WORDS = 0x%08lx.\n", LCD_REG(LCD_WORDS));
lcd_tst_mode = 0;
#endif
index = 0;
// Fill the pallette buffer with the lookup table data
// note this buffer is unused in 16-bit/pixel mode
for (i = 0; i < 256; i ++)
{
LCD_REG(LCD_PALLETE + index) = LCD_PALLETE_TFT((((lcd_lut[i][0] & 0xf8) << 8) // Red
| ((lcd_lut[i][1] & 0xfc) << 3) // Green
| (lcd_lut[i][2] >> 3))); // Blue
index += 4;
}
// initialize the globals
lcd_fg_color = LCD_FG_DEF;
lcd_bg_color = LCD_BG_DEF;
lcd_row = 0;
lcd_col = 0;
lcd_fb_offset = 0x00;
// fill the screen with the background color, remember for the console driver
// we do double buffering, so fill twice as mush as the active screen size
switch (lcd_color_depth){
case 4: temp16 = lcd_bg_color | lcd_bg_color << 4 | lcd_bg_color << 8 | lcd_bg_color << 12; break;
case 8: temp16 = lcd_bg_color | lcd_bg_color << 8; break;
default: temp16 = lcd_bg_color; break;
}
for (i = 0; i < (PIXELS_PER_COL * PIXELS_PER_ROW) * 2; i += 2){
LCD_BUF(i) = temp16;
}
return 0;
}
//--------------------------------------------------------------------------
// lcd_on
//
// This function turns on the PXA250 LCD Controller and the Backlight Inverter
//
void lcd_on()
{
// Make sure it's off first
lcd_off();
// Turn on the LCD Controller
LCD_REG(LCD_DMA0) = LCD_DMA0_ADD(LCD_BUF_ADD); // frame buffer start address
#ifdef LCD_DBG
lcd_tst_mode = 1;
printf("Au1100 LCD_DMA0 = 0x%08lx.\n", LCD_REG(LCD_DMA0));
lcd_tst_mode = 0;
#endif
LCD_REG(LCD_CTL) |= LCD_CTL_GO; // Go!
#ifdef LCD_DBG
lcd_tst_mode = 1;
printf("Au1100 LCD_CTL = 0x%08lx.\n", LCD_REG(LCD_CTL));
lcd_tst_mode = 0;
#endif
udelay(1000);
// Enable the Backlight
LCD_REG(LCD_PWMHI) |= LCD_PWMHI_PWM0(0xfff); // 100% duty cycle = always on
// wait for power-up sequence to complete
udelay(10000);
}
//--------------------------------------------------------------------------
// lcd_off
//
// This function turns off the LCD Controller and the LCD backlight
//
void lcd_off()
{
return;
// Turn off the LCD Controller by clearing the go bit
// first see if it was on
if (LCD_REG(LCD_CTL) & LCD_CTL_GO)
{
LCD_REG(LCD_CTL) &= ~LCD_CTL_GO;
// Wait for the shutdown bit to go true
// while(!(LCD_REG(LCD_ISTAT) & LCD_INT_SD)) {}
udelay(10000);
}
// Turn off the backlight
LCD_REG(LCD_PWMHI) &= ~(LCD_PWMHI_PWM0(0xfff));
}
char *lcd_tstHelp[] = {
" This command allows the user to test ",
" the Au1100 LCD Controller. The user ",
" may set the color depth to run the ",
" test at. Note that the frame buffer ",
" R/W test will test all of the frame ",
" buffer regardless of depth.\n",
" Usage:",
" sed_tst -[n,x,d:[4,8,16]]",
" Options...",
" -n run test without keycheck - CAUTION: RESET SYSTEM TO STOP!",
" -d4 run test, force a depth of 4-bits/pixel",
" -d8 run test, force a depth of 8-bits/pixel",
" -d16 run test, force a depth of 16-bits/pixel",
" -x init only, do not run frame buffer tests",
" no options, default to current mode and depth",
0
};
int lcd_tst(int argc,char *argv[])
{
volatile ushort wr16, rd16;
int i, x, opt;
int no_wait = 0;
int init_only = 0;
char c;
lcd_tst_mode = 1;
lcd_off();
while ((opt=getopt(argc,argv,"clnsxd:4,8,16")) != -1) {
switch(opt) {
case 'd': // set the color depth
switch(*optarg) {
case '4':
lcd_color_depth = 4;
printf("Forcing 4bpp Mode!\n");
break;
case '8':
lcd_color_depth = 8;
printf("Forcing 8bpp Mode!\n");
break;
default: // test with 16bpp
lcd_color_depth = 16;
printf("Forcing 16bpp Mode!\n");
break;
}
break;
case 'n': // no waiting for keypress - fastest operation
no_wait = 1;
printf("No Keypress Mode, Must Reset System to Stop!\n");
break;
case 'x': // init only
no_wait = 1;
printf("Initializing LCD, Skipping testsp!\n");
init_only = 1;
break;
default: // test with current mode
break;
}
}
// get the new parameters into the LCD controller
lcd_init();
lcd_on();
if (init_only) return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -