Linux 2.6.22.19 to S3C2410 (gec2410)

Source: Internet
Author: User

From: http://hi.baidu.com/iblogiam/item/9a608ae2357fbfa8c10d75db

 

Limuscle: The following operations are feasible and have been tested.

Linux 2.6.22.19 porting to S3C2410 (GEC2410): LCD Driver porting

Linux 2.6.22.19 porting to S3C2410 (GEC2410): LCD Driver porting

References:
1. Porting Linux2.6.22.2 to botron 2410-S (s3c2410A) (Supplement: LCD Driver transplantation)
Http://blog.chinaunix.net/u1/34474/showart_410311.html
2. 2410 LCD Driver LTV350QV
Http://blog.chinaunix.net/u2/83636/showart_1733013.html
3. Copyright: Liu liguo is a classic LCD transplant document. This document is required before transplantation. Google is available on the Internet (PDF version ).

Platform information:
Target Board: GEC2410
OS: Fedora Cor8 (FC8)
Compiler: arm-2007q3-53-arm-none-eabi-i686-pc-linux-gnu (4.2.1)
LCD: LTV350QV_FOE 3.5 inch 320x240 of SUMSANG

Note before migration:
If you are porting the 2.6.24 kernel, I think you should stop looking at it. There are many differences with 2.6.22:
I. There was a major data structure change in the 2.6.24 kernel. First, he split the structure into two parts. One structure is s3c2410fb_display, And the other structure is s3c2410fb_mach_info, therefore, the preceding structure is split based on the two data structures;
2, 2.6.24 structure of the register lcdcon1-4 all with the function for automatic settings, we only need to set the lcdcon5, but does not indicate that other data is not important, or do not need to set, only focus on the lcdcon5 values.
For details about Linux driver 2.6.24, refer:
Linux 2.6.24.4 port to S3C2410 (nano2410): LCD

Procedure:
Linux. (However, the LTV350QV LCD should be discussed separately. We will introduce it in detail below )!!!
1. Modify/arch/arm/mach-s3c2410/mach-smdk2410.c files
1). Add a header file
# Include <asm/arch/fb. h>

2). Add parameters required to initialize the LCD controller of s3c2410 (these parameters can be copied directly from the mach-qt2410.c file at the same level directory and slightly modified, increase the porting speed ).
Static struct s3c2410fb_mach_info S3C2410_ LCD _cfg _ initdata = {
. Type = s3c2410_lcdconw.tft, // This is very important. Please refer to the following special instructions (1)
. Regs = {// see the special instructions (2)
. Lcdcon1 = s3c2410_lcdconw.tft16bpp |
S3c2410_lcdconw.tft |
S3C2410_LCDCON1_CLKVAL (0x04 ),
. Lcdcon2 = S3C2410_LCDCON2_VBPD (5) |
S3C2410_LCDCON2_LINEVAL (239) |
S3C2410_LCDCON2_VFPD (4) |
S3C2410_LCDCON2_VSPW (3 ),
. Lcdcon3 = S3C2410_LCDCON3_HBPD (13) |
S3C2410_LCDCON3_HOZVAL (319) |
S3C2410_LCDCON3_HFPD (20 ),
. Lcdcon4 = S3C2410_LCDCON4_MVAL (13) |
S3C2410_LCDCON4_HSPW (18 ),
. Lcdcon5 = S3C2410_LCDCON5_FRM565 |
S3C2410_LCDCON5_INVVLINE |
S3C2410_LCDCON5_INVVFRAME |
S3C2410_LCDCON5_PWREN |
S3C2410_LCDCON5_INVVCLK |
S3c2410_lcdcon5_hwswp,
},
. Width = 320,
. Size = 240,
. Xres = {
. Min = 320,
. Max = 320,
. Defval = 320,
},
. Yres = {
. Min = 240,
. Max = 240,
. Defval = 240,
},
. Bpp = {
. Min = 16,
. Max = 16,
. Defval = 16,
},
// Note the following settings (3)
. Gpcup = 0 xffffffff, // disable pulling
. Gpcup_mask = 0 xffffffff, // _ mask is used to clear registers
. Gpccon = 0xaa9556a9,
. Gpccon_mask = 0 xffffffff,
. Gpdup = 0 xffffffff,
. Gpdup_mask = 0 xffffffff,
. Gpdcon = 0 xaaaaaaaa,
. Gpdcon_mask = 0 xffffffff,
. Lpcsel = 0x00, // LPC3600
};

3) Add the register parameter setting function of the LCD controller.
Static void _ init smdk2410_init (void)
{
S3c24xx_fb_set_platdata (& qt2410_biglcd_cfg );
Platform_add_devices (smdk2410_devices, ARRAY_SIZE (smdk2410_devices ));
Smdk_machine_init ();
}

Note:
(1) among them, ". type = s3c2410_lcdconw.tft," must be added. Otherwise, Linux will think that the LCD screen is an STN screen and the screen appears (blue like rain ).

(2) The regs settings for different LCD styles are different. You need to set them according to your own LCD configuration. You can refer to the LCD manual, you can also COPY it directly from the LCD driver that comes with the Development Board. The driver that comes with the Development Board is generally driver/video/s3c2410fp. c. I just copied it directly. below is the part of the driver that comes with my Development Board:
. Regs = {
. Lcdcon1 = (5 <8) | (0 <7) | (3 <5) | (12 <1 ),
. Lcdcon2 = (5 <24) | (239 <14) | (4 <6) | (3 ),
. Lcdcon3 = (13 <19) | (319 <8) | (20 ),
. Lcdcon4 = (13 <8) | (18 ),
. Lcdcon5 = (1 <11) | (1 <10) | (1 <9) | (1 <8) | (0 <6) | (0 <1) | (1 ),
},
You can simply use a number instead of a variable !!!

(3) The settings here can be determined based on the LCD schematic and manual, but the more convenient way is the same as setting regs, directly from the driver/video/s3c2410fb that comes with the Development Board. search for the c LCD driver !!!
The * _ mask parameter is used to first reset the register parameters to be modified. This ensures that the subsequent settings are correct. The setting operation is a placement operation and cannot be cleared (refer to my reference 1 ). If you want to know the functions of other items, read the manual on your own. There are enough details !!!
Okay, mach-smdk2410.c File Modification ended .!!!!
________________________________________

2. If you want to disable the LCD display function in about 10 minutes, perform the second step!

The method is very simple. Just comment out the function content of the drivers \ char \ vt. c's blank_screen_t (unsigned long dummy !!! However, I don't want to remove this function in general cases. It can save power and prolong the LCD service life. Why bother me !!!
________________________________________

3. Compile the kernel and select the driver to be installed.
# Make menuconfig
Device Drivers>
Graphics support --->
<*> Support for frame buffer devices
<*> S3C2410 LCD framebuffer support
Console display driver support --->
<*> Framebuffer Console support

[*] Framebuffer Console Rotation

[*] Select compiled-in fonts

[*] VGA 8x8 font
[*] VGA 8x16 font

[*] Mini 4x6 font
[*] ISCSI console 8x16 font
[*] Bootup logo --->
[*] Standard 224-color Linux logo
________________________________________

4. If you are not an LCD OF THE LTV350QV_FOE series, you will generally finish your work. Just make zImage to compile the kernel and burn it.
________________________________________

However, if you are lucky enough to use the LTV350QV_FOE series LCDHaha, keep a good attitude and continue to come with me !!! Really, mentality is very important! I was also very depressed at the time and reluctantly moved on to the transplant. As a result, I had to pay a terrible price and wasted my whole day !!! But it's also a bit strange to me that I wrote the second reference document. If I did it, I should write it clearly! It's always a bit of it. It's a little bit of it. You think you're very subtle !!!! What are you doing ~~~!!!!!
(This LTV350QV is special. Its initialization needs to write the internal register of S6F2002 through the spi bus. Some people say that LTV350QV is troublesome and must be configured through SPI, but this is also a flexible aspect .) This is what the Birdman said. I don't know if this is the case. Let's judge it by yourself !!!!

5. Okay. Don't say anything. Come on, let's continue !!!
It's actually quite easy, that is, adding an initial LCD function to driver/video/s3c2410fb. c !!! This function is directly integrated with the driver of the Development Board !! If you want to write it on your own, you can write it from your reference manual. I forget it. It's very depressing !!!!
Below is my own s3c2410fb Based on the Development Board. c driver Concatenates the initialization LCD code and adds it to driver/video/s3c2410fb. c: (Note: You must use my code directly based on the driver of your own development board. Sorry, I cannot guarantee that you can port it successfully ~~~~)
Part 1 (Definition ):
Typedef struct _ LTV350qv_spi_data _{
Unsigned char Device_ID; // ID of the device
Unsigned int Index; // index of register
Unsigned long Structure; // structure to be writed
} LTV350QV_SPI_Data;

// Micro for LTV350QV_POE
# Define CS_H _ raw_writel (_ raw_readl (S3C2410_GPCDAT) | (1 <8), S3C2410_GPCDAT) // MAKE_HIGH (LTV350QV_CS)
# Define CS_L _ raw_writel (_ raw_readl (S3C2410_GPCDAT )&~ (1 <8), S3C2410_GPCDAT) // MAKE_LOW (LTV350QV_CS)
# Define SCLK_H _ raw_writel (_ raw_readl (S3C2410_GPCDAT) | (1 <9), S3C2410_GPCDAT) // MAKE_HIGH (ltv350qv_cl)
# Define SCLK_L _ raw_writel (_ raw_readl (S3C2410_GPCDAT )&~ (1 <9), S3C2410_GPCDAT) // MAKE_LOW (LTV350QV_SCL)
# Define SDI_H _ raw_writel (_ raw_readl (S3C2410_GPCDAT) | (1 <10), S3C2410_GPCDAT) // MAKE_HIGH (LTV350QV_SDI)
# Define SDI_L _ raw_writel (_ raw_readl (S3C2410_GPCDAT )&~ (1 <10), S3C2410_GPCDAT) // MAKE_LOW (LTV350QV_SDI)
# Define RST_H _ raw_writel (_ raw_readl (S3C2410_GPDDAT) | (1 <0), S3C2410_GPDDAT) // MAKE_HIGH (LTV350QV_RST)
# Define RST_L _ raw_writel (_ raw_readl (S3C2410_GPDDAT )&~ (1 <0), S3C2410_GPDDAT) // MAKE_LOW (LTV350QV_RST)

Part 2 (initial function ):
//************************************** *************************
// ********** These functions for SUMSUN LTV350QV tft LCD ****************
//************************************** *************************
// Short delay for about 90 * time ns
Static void LTV350QV_Short_Delay (u_char time)
{
// U_char I;
// For (I = 0; I <time * 10; I ++); // about 180 ns
Ndelay (150 );
}

Static void LTV350QV_Rst (void)
{
RST_L;
Mdelay (1 );
RST_H;
Mdelay (1 );
}

Static void LTV350QV_Register_Write (LTV350QV_SPI_Data regdata)
{
U_char I, temp1;
U_int temp2;
U_long temp3;
Unsigned long flags;

// Write index
Temp1 = regdata. Device_ID <2 | 0 <1 | 0 <0; // register index
Temp2 = regdata. Index;
Temp3 = (temp1 <24) | (temp2 <8 );

Local_irq_save (flags );

CS_L;
LTV350QV_Short_Delay (1 );
For (I = 0; I <24; I ++)
{
SCLK_L;
If (temp3 & (1 <(31-i) // if is H
SDI_H;
Else
SDI_L;
LTV350QV_Short_Delay (1); // setup time
SCLK_H;
Ltv350qv_short_delay (1); // hold time
}
Cs_h;

Ltv350qv_short_delay (5 );

// Write instruction
Temp1 = regdata. device_id <2 | 1 <1 | 0 <0; // instruction
Temp2 = regdata. structure;
Temp3 = (temp1 <24) | (temp2 <8 );

Cs_l;
Ltv350qv_short_delay (1 );
For (I = 0; I <24; I ++)
{
Sclk_l;
If (temp3 & (1 <(31-i) // If is H
Sdi_h;
Else
Sdi_l;
Ltv350qv_short_delay (1 );
SCLK_H;
LTV350QV_Short_Delay (1 );
}
CS_H;

Local_irq_restore (flags );
}

/*************************************** *
**
****************************************/
Static void LTV350QV_Write (u_int index, u_int regdata)
{
LTV350QV_SPI_Data WriteData;

WriteData. Device_ID = LTV350QV_POE; // 0x1d
WriteData. Index = index ;//
WriteData. Structure = regdata;

LTV350QV_Register_Write (WriteData );
}
/*************************************** *
** Power ON sequence
****************************************/
Static void ltv350qv_power_on (void) // for the pink part of the code, see the pxafb_setup_gpio section of the built-in driver. Alternatively, you can track the ltv350qv_power_on function and find the specific implementation code !!!
{
_ Raw_writel (0xaa9556a9, s3c2410_gpccon); // initialize VD [], lcdvf [], Vm, vframe, vline, vclk, lend
// Lcdvf [0], [1], [2] --- output; Vd [0], [1], [2] ---- output.

_ Raw_writel (0 xffffffff, s3c2410_gpcup); // disable pull-up register

// DPRINTK ("% s () \ n", _ FUNCTION __);

LTV350QV_Write (9, 0x0000 );
Mdelay (150 );
LTV350QV_Write (9, 0x4000 );
LTV350QV_Write (10, 0x2000 );
LTV350QV_Write (9, 0x4055 );
Mdelay (550 );
LTV350QV_Write (1, 0x409d );
LTV350QV_Write (2, 0x0204 );
LTV350QV_Write (3, 0x0100 );
LTV350QV_Write (4, 0x3000 );
LTV350QV_Write (5, 0x4003 );
LTV350QV_Write (6, 0x000a );
LTV350QV_Write (7, 0x0021 );
LTV350QV_Write (8, 0x0c00 );
LTV350QV_Write (10, 0x0103 );
LTV350QV_Write (11, 0x0301 );
LTV350QV_Write (12, 0x1f0f );
LTV350QV_Write (13, 0x1f0f );
LTV350QV_Write (14, 0x0707 );
LTV350QV_Write (15, 0x0307 );
LTV350QV_Write (16, 0x0707 );
LTV350QV_Write (17, 0x0000 );
LTV350QV_Write (18, 0x0004 );
LTV350QV_Write (19, 0x0000 );

Mdelay (200 );
LTV350QV_Write (9, 0x4a55 );
LTV350QV_Write (5, 0x5003 );

_ Raw_writel (0 xaaaaaaaa, S3C2410_GPDCON );
_ Raw_writel (0 xffffffff, S3C2410_GPDUP );
_ Raw_writel (3, S3C2410_LCDINTMSK); // mask LCD Sub Interrupt
_ Raw_writel (0, S3C2410_TPAL); // Disable Temp Palette
_ Raw_writel (0, S3C2410_LPCSEL); // Disable LPC3600
}

/**********************************
** Power OFF sequence
**********************************/
Static void LTV350QV_Powen_OFF (void) // useless
{

/* GON-> 0, POC-> 0 */
LTV350QV_Write (9, 0x4055 );
/* DSC-> 0 */
LTV350QV_Write (5, 0x4003 );
/* VCOMG-> 0 */
LTV350QV_Write (10, 0x0000 );

Mdelay (20 );

/* AP [2: 0]-> 000 */
LTV350QV_Write (9, 0x4000 );
}
// ---------------------------------------------------------- End LTV350-POE

Part 3 (add the above LTV350QV_Power_ON function to the execution ):
The position to be added is static int _ init s3c2410fb_probe (struct platform_device * pdev). The specific position is added:
Ret = s3c2410fb_init_registers (info );
Ret = s3c2410fb_check_var (& fbinfo-> var, fbinfo );
Ret = register_framebuffer (fbinfo );
If (ret <0 ){
Printk (KERN_ERR "Failed to register framebuffer device: % d \ n", ret );
Goto free_video_memory;
}
LTV350QV_Power_ON ();
Can other locations be used? SORRY, I don't know. You can do it !!! Haha, if you are interested, you can try it !!!!

6. How are you doing? This fifth step is awesome !!! But it's okay. That's all !!!If you forget to configure the kernel, configure it. The options are the same as those above! Then compile the kernel, burn the Development Board, and start ..... Have you seen the cute penguin image displayed on the LCD ??? Yes? Haha... Congratulations! If you do not see it, check again if it is missing, but be sureMaintain a good attitudeOh, this is very important !!!!
The startup information is as follows:
Console: switching to color frame buffer device 80x40
Fb0: s3c2410fb frame buffer device

7. If you want to display your Logo on the LCD, I will introduce the custom Logo method below:
(1) Go to The kde graphic interface of linux, use The GIMP image editor (or others) to open The image file you want, and select image> mode> index color, change the color to 224. The image size should not be greater than the resolution of your monitor. Finally, save the file in the ppm format (ASCii code). The file name is logo_linux_clut224.ppm.
(2) Copy logo_linux_clut224.ppm to the/drivers/video/logo folder and replace the original file (remember to back up the file, just in case ).
(3) recompile the kernel and start the development board.

8. Share good articles (find them online)

1.
LCD Driving Analysis of Linux-2.6.20

2. LCD transplantation process

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.