/*!
* \file
* \author:<hebh@amoi.com.cn>
* \date 2008-1-14 15:00:18
* \version 1.0
* \brief
* \log: wangxf porting lcd init code of mobile in 2008.01.19
*/
#include <config.h>
#include <common.h>
#include <version.h>
#include <stdarg.h>
#include <linux/types.h>
#include <devices.h>
#include <lcd.h>
#include "amoi_logo.h"
#ifdef CONFIG_LCD
vidinfo_t panel_info = {
vl_col: 240,
vl_row: 320,
vl_width: 240,
vl_height: 320,
vl_clkp: CFG_HIGH,
vl_oep: CFG_HIGH,
vl_hsp: CFG_HIGH,
vl_vsp: CFG_HIGH,
vl_dp: CFG_HIGH,
vl_bpix: 4,
vl_lbw: 1,
vl_splt: 0,
vl_clor: 1,
vl_tft: 1,
vl_hpw: 1,
vl_blw: 1,
vl_elw: 1,
vl_vpw: 7,
vl_bfw: 0,
vl_efw: 0,
};
int lcd_line_length;
int lcd_color_fg;
int lcd_color_bg;
void *lcd_base; /* Start of framebuffer memory */
void *lcd_console_address; /* Start of console buffer */
short console_col;
short console_row;
/*----------------------------------------------------------------------*/
#if LCD_BPP == LCD_COLOR8
void
lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
{
unsigned short *palette;
u_int val;
val = ((red << 8) & 0xf800)|
((green << 4) & 0x07e0)|
(blue & 0x001f);
#ifdef LCD_INVERT_COLORS
palette[regno] = ~val;
#else
palette[regno] = val;
#endif
debug ("setcolreg: reg %2d @ %p: R=%02X G=%02X B=%02X => %04X\n",
regno, &palette[regno],
red, green, blue,
palette[regno]);
}
#endif /* LCD_COLOR8 */
void lcd_enable (void)
{
}
/*
* Calculate fb size for VIDEOLFB_ATAG. Size returned contains fb,
* descriptors and palette areas.
*/
ulong calc_fbsize (void)
{
ulong size;
int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
size = line_length * panel_info.vl_row;
size += PAGE_SIZE;
return size;
}
#include <asm/io.h>
#include <s3c2440.h>
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Type: 函数
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
static int s3cfb_init_mem (void *lcdbase, vidinfo_t *vid)
{
struct s3cfb_info *fbi = &vid->s3c;
fbi->screen = (u_long)lcdbase;
return 0;
}
static S3C24X0_GPIO* g_s2440IOP = NULL;
static S3C24X0_LCD* g_s2440LCD = NULL;
static S3C24X0_CLOCK_POWER* g_sCLKPWRReg = NULL;
//#define writeb(v,a) __arch_putb(v,a)
//#define writew(v,a) __arch_putw(v,a)
#define OUTREG32(a,v) writel(v,a)
//#define readb(a) __arch_getb(a)
//#define readw(a) __arch_getw(a)
#define INREG32(a) readl(a)
#define SETREG32(x, y) OUTREG32(x, INREG32(x)|(y))
#define CLRREG32(x, y) OUTREG32(x, INREG32(x)&~(y))
#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
#define LCD_DELAY_1MS 1000
#define LCD_DEN_Lo CLRREG32(&g_s2440IOP->GPDDAT,SPI_CS);
#define LCD_DEN_Hi SETREG32(&g_s2440IOP->GPDDAT,SPI_CS);
#define LCD_DCLK_Lo CLRREG32(&g_s2440IOP->GPDDAT,SPI_SCL);
#define LCD_DCLK_Hi SETREG32(&g_s2440IOP->GPDDAT,SPI_SCL);
#define LCD_DSERI_Lo CLRREG32(&g_s2440IOP->GPDDAT,SPI_SDA);
#define LCD_DSERI_Hi SETREG32(&g_s2440IOP->GPDDAT,SPI_SDA);
#define dimof(x) (sizeof(x)/sizeof(x[0]))
#define VAR_MAP_OFF 0x90000000
static void initspi(void)
{
//init GPIO for spi emulating
CLRREG32(&g_s2440IOP->GPDCON,((3<<(SPI_CS_D0IO*2))|(3<<(SPI_SCL_D1IO*2))|(3<<(SPI_SDA_D9IO*2))));
SETREG32(&g_s2440IOP->GPDCON,((1<<(SPI_CS_D0IO*2))|(1<<(SPI_SCL_D1IO*2))|(1<<(SPI_SDA_D9IO*2))));
SETREG32(&g_s2440IOP->GPDUP,((1<<(SPI_CS_D0IO))|(1<<(SPI_SCL_D1IO))|(1<<(SPI_SDA_D9IO))));
LCD_DEN_Hi;
LCD_DCLK_Hi;
LCD_DSERI_Hi;
}
static void spi_sendbyte(u8 data)
{
u8 senddata=data;
s8 i;
u8 DELAY=1;
LCD_DEN_Lo; // EN = Low CS Low
udelay(DELAY);
for (i= 7; i>= 0; i--)
{
LCD_DCLK_Lo; // SCL Low
udelay(DELAY);
if ((senddata >> i) & 0x01) // DATA HIGH or LOW
{
LCD_DSERI_Hi;
}
else
{
LCD_DSERI_Lo;
}
udelay(DELAY);
LCD_DCLK_Hi; // CLOCK = High
udelay(DELAY);
}
}
static void spi_write_config(LCD_CONFIG_DATA *config_data)
{
u8 comm_addr= config_data->comm_addr;
#if defined(LCD_TD028TTEC1)||defined(LCD_ST7787)||defined(LCD_ILI9320DS)||defined(LCD_LGDP4531)
u16 conf_data = config_data->conf_data;
#elif defined(LCD_L4F00242T05)
u32 conf_data = config_data->conf_data;
#else
u8 conf_data = config_data->conf_data;
#endif
u32 DELAY=1;
if(0xff != comm_addr)
#if defined(LCD_TD028TTEC1)||defined(LCD_ST7787)
{
UINT16 senddata;
UINT8 count = config_data->count;
INT8 i=0;
LCD_DEN_Lo; // EN = Low CS Low
udelay(DELAY);
if(comm_addr != 0xfe) //check write comm or para
{
// RETAILMSG(1,(L"LCD_TD028TTEC1 spi_write_config\r\n"));
LCD_DCLK_Lo; // EN = Low CS Low
udelay(DELAY);
LCD_DSERI_Lo; //data low ,following send command
udelay(DELAY);
LCD_DCLK_Hi; // CLOCK = High
udelay(DELAY);
senddata = comm_addr;
spi_sendbyte((UINT8)senddata);
}
while(count--)
{
LCD_DCLK_Lo; // CLOCK = Low
udelay(DELAY);
LCD_DSERI_Hi; //data high ,following send parameter
udelay(DELAY);
LCD_DCLK_Hi;
udelay(DELAY);
senddata = (conf_data>> (count*8));
spi_sendbyte((UINT8)senddata);
}
LCD_DEN_Hi; // EN = High CS high
LCD_DCLK_Hi; // CLOCK = Low
LCD_DSERI_Hi;
}
#elif defined(LCD_L4F00242T05)
{
UINT32 senddata;
UINT8 count = config_data->count;
LCD_DEN_Lo; // EN = Low CS Low
udelay(DELAY);
LCD_DCLK_Lo; // EN = Low CS Low
udelay(DELAY);
LCD_DSERI_Lo; //data low ,following send command
udelay(DELAY);
LCD_DCLK_Hi; // CLOCK = High
udelay(DELAY);
senddata = (UINT8)comm_addr;
spi_sendbyte((UINT8)senddata);
LCD_DEN_Hi; // EN = High CS high
udelay(DELAY);
while(count--)
{
LCD_DEN_Lo; // EN = Low CS high
udelay(DELAY);
LCD_DCLK_Lo; // CLOCK = Low
udelay(DELAY);
LCD_DSERI_Hi; //data high ,following send parameter
udelay(DELAY);
LCD_DCLK_Hi;
udelay(DELAY);
senddata =(UINT8)(conf_data>> (count*8));
spi_sendbyte((UINT8)senddata);
LCD_DEN_Hi; // EN = High CS high
udelay(DELAY);
}
LCD_DEN_Hi; // EN = High CS high
LCD_DCLK_Hi; // CLOCK = Low
LCD_DSERI_Hi;
}
#elif defined(LCD_BM240320_4252FTGAN)
{
UINT8 start_byte;
//send index reg first.
LCD_DEN_Lo; // EN = Low CS Low
udelay(DELAY);
//send start byte first for command addr write.
start_byte = LDIC_STARTBYTE_IDXWRITE;
spi_sendbyte(start_byte);
spi_sendbyte(comm_addr);
LCD_DEN_Hi; // EN = High CS