update for rk29 fb driver

This commit is contained in:
zyw
2010-12-03 23:28:10 +08:00
parent e7bbb582db
commit c5592682d9
6 changed files with 180 additions and 203 deletions

View File

@@ -111,155 +111,48 @@ static struct rk29_gpio_bank rk29_gpiobankinit[] = {
* author: zyw@rock-chips.com
*****************************************************************************************/
//#ifdef CONFIG_LCD_TD043MGEA1
#define LCD_TXD_PIN RK29_PIN0_PA6 // <20><><EFBFBD><EFBFBD>,<2C><><EFBFBD>޸<EFBFBD>
#define LCD_CLK_PIN RK29_PIN0_PA7 // <20><><EFBFBD><EFBFBD>,<2C><><EFBFBD>޸<EFBFBD>
#define LCD_CS_PIN RK29_PIN0_PB6 // <20><><EFBFBD><EFBFBD>,<2C><><EFBFBD>޸<EFBFBD>
#define LCD_TXD_MUX_NAME GPIOE_U1IR_I2C1_NAME
#define LCD_CLK_MUX_NAME NULL
#define LCD_CS_MUX_NAME GPIOH6_IQ_SEL_NAME
#define LCD_TXD_MUX_MODE 0
#define LCD_CLK_MUX_MODE 0
#define LCD_CS_MUX_MODE 0
#define LCD_TXD_PIN INVALID_GPIO
#define LCD_CLK_PIN INVALID_GPIO
#define LCD_CS_PIN INVALID_GPIO
/*****************************************************************************************
* frame buffe devices
* author: zyw@rock-chips.com
*****************************************************************************************/
#define FB_ID 0
#define FB_DISPLAY_ON_PIN RK29_PIN6_PD0
#define FB_LCD_STANDBY_PIN RK29_PIN6_PD1
#define FB_MCU_FMK_PIN INVALID_GPIO
#define FB_DISPLAY_ON_VALUE GPIO_HIGH
#define FB_LCD_STANDBY_VALUE GPIO_HIGH
//#endif
static int rk29_lcd_io_init(void)
{
int ret = 0;
#if 0
rk29_mux_api_set(LCD_CS_MUX_NAME, LCD_CS_MUX_MODE);
if (LCD_CS_PIN != INVALID_GPIO) {
ret = gpio_request(LCD_CS_PIN, NULL);
if(ret != 0)
{
goto err1;
printk(">>>>>> lcd cs gpio_request err \n ");
}
}
rk29_mux_api_set(LCD_CLK_MUX_NAME, LCD_CLK_MUX_MODE);
if (LCD_CLK_PIN != INVALID_GPIO) {
ret = gpio_request(LCD_CLK_PIN, NULL);
if(ret != 0)
{
goto err2;
printk(">>>>>> lcd clk gpio_request err \n ");
}
}
rk29_mux_api_set(LCD_TXD_MUX_NAME, LCD_TXD_MUX_MODE);
if (LCD_TXD_PIN != INVALID_GPIO) {
ret = gpio_request(LCD_TXD_PIN, NULL);
if(ret != 0)
{
goto err3;
printk(">>>>>> lcd txd gpio_request err \n ");
}
}
return 0;
err3:
if (LCD_CLK_PIN != INVALID_GPIO) {
gpio_free(LCD_CLK_PIN);
}
err2:
if (LCD_CS_PIN != INVALID_GPIO) {
gpio_free(LCD_CS_PIN);
}
err1:
#endif
return ret;
}
static int rk29_lcd_io_deinit(void)
{
int ret = 0;
#if 0
gpio_direction_output(LCD_CLK_PIN, 0);
gpio_set_value(LCD_CLK_PIN, GPIO_HIGH);
gpio_direction_output(LCD_TXD_PIN, 0);
gpio_set_value(LCD_TXD_PIN, GPIO_HIGH);
gpio_free(LCD_CS_PIN);
rk29_mux_api_mode_resume(LCD_CS_MUX_NAME);
gpio_free(LCD_CLK_PIN);
gpio_free(LCD_TXD_PIN);
rk29_mux_api_mode_resume(LCD_TXD_MUX_NAME);
rk29_mux_api_mode_resume(LCD_CLK_MUX_NAME);
#endif
return ret;
}
struct rk29lcd_info rk29_lcd_info = {
//.txd_pin = LCD_TXD_PIN,
//.clk_pin = LCD_CLK_PIN,
//.cs_pin = LCD_CS_PIN,
.txd_pin = LCD_TXD_PIN,
.clk_pin = LCD_CLK_PIN,
.cs_pin = LCD_CS_PIN,
.io_init = rk29_lcd_io_init,
.io_deinit = rk29_lcd_io_deinit,
};
/*****************************************************************************************
* frame buffe devices
* author: zyw@rock-chips.com
*****************************************************************************************/
#define FB_ID 0
#define FB_DISPLAY_ON_PIN RK29_PIN0_PB1 // <20><><EFBFBD><EFBFBD>,<2C><><EFBFBD>޸<EFBFBD>
#define FB_LCD_STANDBY_PIN INVALID_GPIO
#define FB_MCU_FMK_PIN INVALID_GPIO
#if 0
#define FB_DISPLAY_ON_VALUE GPIO_LOW
#define FB_LCD_STANDBY_VALUE 0
#define FB_DISPLAY_ON_MUX_NAME GPIOB1_SMCS1_MMC0PCA_NAME
#define FB_DISPLAY_ON_MUX_MODE IOMUXA_GPIO0_B1
#define FB_LCD_STANDBY_MUX_NAME NULL
#define FB_LCD_STANDBY_MUX_MODE 1
#define FB_MCU_FMK_PIN_MUX_NAME NULL
#define FB_MCU_FMK_MUX_MODE 0
#define FB_DATA0_16_MUX_NAME GPIOC_LCDC16BIT_SEL_NAME
#define FB_DATA0_16_MUX_MODE 1
#define FB_DATA17_18_MUX_NAME GPIOC_LCDC18BIT_SEL_NAME
#define FB_DATA17_18_MUX_MODE 1
#define FB_DATA19_24_MUX_NAME GPIOC_LCDC24BIT_SEL_NAME
#define FB_DATA19_24_MUX_MODE 1
#define FB_DEN_MUX_NAME CXGPIO_LCDDEN_SEL_NAME
#define FB_DEN_MUX_MODE 1
#define FB_VSYNC_MUX_NAME CXGPIO_LCDVSYNC_SEL_NAME
#define FB_VSYNC_MUX_MODE 1
#define FB_MCU_FMK_MUX_NAME NULL
#define FB_MCU_FMK_MUX_MODE 0
#endif
static int rk29_fb_io_init(struct rk29_fb_setting_info *fb_setting)
{
int ret = 0;
#if 0
if(fb_setting->data_num <=16)
rk29_mux_api_set(FB_DATA0_16_MUX_NAME, FB_DATA0_16_MUX_MODE);
if(fb_setting->data_num >16 && fb_setting->data_num<=18)
rk29_mux_api_set(FB_DATA17_18_MUX_NAME, FB_DATA17_18_MUX_MODE);
if(fb_setting->data_num >18)
rk29_mux_api_set(FB_DATA19_24_MUX_NAME, FB_DATA19_24_MUX_MODE);
if(fb_setting->vsync_en)
rk29_mux_api_set(FB_VSYNC_MUX_NAME, FB_VSYNC_MUX_MODE);
if(fb_setting->den_en)
rk29_mux_api_set(FB_DEN_MUX_NAME, FB_DEN_MUX_MODE);
if(fb_setting->mcu_fmk_en && FB_MCU_FMK_MUX_NAME && (FB_MCU_FMK_PIN != INVALID_GPIO))
if(fb_setting->mcu_fmk_en && (FB_MCU_FMK_PIN != INVALID_GPIO))
{
rk29_mux_api_set(FB_MCU_FMK_MUX_NAME, FB_MCU_FMK_MUX_MODE);
ret = gpio_request(FB_MCU_FMK_PIN, NULL);
if(ret != 0)
{
@@ -268,10 +161,8 @@ static int rk29_fb_io_init(struct rk29_fb_setting_info *fb_setting)
}
gpio_direction_input(FB_MCU_FMK_PIN);
}
if(fb_setting->disp_on_en && FB_DISPLAY_ON_MUX_NAME && (FB_DISPLAY_ON_PIN != INVALID_GPIO))
if(fb_setting->disp_on_en && (FB_DISPLAY_ON_PIN != INVALID_GPIO))
{
rk29_mux_api_set(FB_DISPLAY_ON_MUX_NAME, FB_DISPLAY_ON_MUX_MODE);
ret = gpio_request(FB_DISPLAY_ON_PIN, NULL);
if(ret != 0)
{
@@ -280,9 +171,8 @@ static int rk29_fb_io_init(struct rk29_fb_setting_info *fb_setting)
}
}
if(fb_setting->disp_on_en && FB_LCD_STANDBY_MUX_NAME && (FB_LCD_STANDBY_PIN != INVALID_GPIO))
if(fb_setting->disp_on_en && (FB_LCD_STANDBY_PIN != INVALID_GPIO))
{
rk29_mux_api_set(FB_LCD_STANDBY_MUX_NAME, FB_LCD_STANDBY_MUX_MODE);
ret = gpio_request(FB_LCD_STANDBY_PIN, NULL);
if(ret != 0)
{
@@ -290,17 +180,16 @@ static int rk29_fb_io_init(struct rk29_fb_setting_info *fb_setting)
printk(">>>>>> FB_LCD_STANDBY_PIN gpio_request err \n ");
}
}
#endif
return ret;
}
struct rk29fb_info rk29_fb_info = {
.fb_id = FB_ID,
//.disp_on_pin = FB_DISPLAY_ON_PIN,
//.disp_on_value = FB_DISPLAY_ON_VALUE,
//.standby_pin = FB_LCD_STANDBY_PIN,
//.standby_value = FB_LCD_STANDBY_VALUE,
//.mcu_fmk_pin = FB_MCU_FMK_PIN,
.disp_on_pin = FB_DISPLAY_ON_PIN,
.disp_on_value = FB_DISPLAY_ON_VALUE,
.standby_pin = FB_LCD_STANDBY_PIN,
.standby_value = FB_LCD_STANDBY_VALUE,
.mcu_fmk_pin = FB_MCU_FMK_PIN,
.lcd_info = &rk29_lcd_info,
.io_init = rk29_fb_io_init,
};

View File

@@ -13,6 +13,8 @@ config LCD_HL070VM4AU
bool "RGB_HL070VM4AU"
config LCD_HSD070IDW1
bool "RGB Hannstar800x480"
config LCD_HSD100PXN
bool "RGB Hannstar HSD100PXN(1024X768)"
config LCD_A060SE02
bool "MCU A060SE02"
config LCD_S1D13521

View File

@@ -17,5 +17,6 @@ obj-$(CONFIG_LCD_NT35580) += lcd_nt35580.o
obj-$(CONFIG_HDMI_ANX7150) += hdmi_anx7150.o
obj-$(CONFIG_LCD_HX8357) += lcd_hx8357.o
obj-$(CONFIG_LCD_HSD100PXN) += lcd_hsd100pxn.o

View File

@@ -0,0 +1,71 @@
#include <linux/fb.h>
#include <linux/delay.h>
#include "../../rk29_fb.h"
#include <mach/gpio.h>
#include <mach/iomux.h>
#include <mach/board.h>
#include "screen.h"
/* Base */
#define OUT_TYPE SCREEN_RGB
#define OUT_FACE OUT_P888
#define OUT_CLK 65
#define LCDC_ACLK 150 //29 lcdc axi DMA Ƶ<><C6B5>
/* Timing */
#define H_PW 10
#define H_BP 100
#define H_VD 1024
#define H_FP 210
#define V_PW 10
#define V_BP 10
#define V_VD 768
#define V_FP 18
/* Other */
#define DCLK_POL 0
#define SWAP_RB 0
void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )
{
/* screen type & face */
screen->type = OUT_TYPE;
screen->face = OUT_FACE;
/* Screen size */
screen->x_res = H_VD;
screen->y_res = V_VD;
/* Timing */
screen->pixclock = OUT_CLK;
screen->left_margin = H_BP;
screen->right_margin = H_FP;
screen->hsync_len = H_PW;
screen->upper_margin = V_BP;
screen->lower_margin = V_FP;
screen->vsync_len = V_PW;
/* Pin polarity */
screen->pin_hsync = 0;
screen->pin_vsync = 0;
screen->pin_den = 0;
screen->pin_dclk = DCLK_POL;
screen->lcdc_aclk = LCDC_ACLK;
/* Swap rule */
screen->swap_rb = SWAP_RB;
screen->swap_rg = 0;
screen->swap_gb = 0;
screen->swap_delta = 0;
screen->swap_dumy = 0;
/* Operation function*/
screen->init = NULL;
screen->standby = NULL;
}

View File

@@ -61,6 +61,7 @@ struct rk29fb_screen {
u8 pin_vsync;
u8 pin_den;
u8 pin_dclk;
u8 lcdc_aclk;
u8 pin_dispon;
/* Swap rule */

View File

@@ -53,9 +53,6 @@
#include "./display/screen/screen.h"
#define CURSOR_BUF_SIZE 256 //rk29 cursor need 256B buf
#if 1
#define fbprintk(msg...) printk(msg);
#else
@@ -125,7 +122,8 @@ struct rk29fb_inf {
struct clk *dclk; //lcdc dclk
struct clk *dclk_parent; //lcdc dclk divider frequency source
struct clk *dclk_divider; //lcdc demodulator divider frequency
struct clk *clk_share_mem; //lcdc share memory frequency
struct clk *aclk; //lcdc share memory frequency
struct clk *aclk_parent; //lcdc aclk divider frequency source
unsigned long dclk_rate;
/* lcdc reg base address and backup reg */
@@ -208,7 +206,7 @@ void set_lcd_pin(struct platform_device *pdev, int enable)
// set display_on
if(display_on != INVALID_GPIO)
{
{
gpio_direction_output(display_on, 0);
gpio_set_value(display_on, enable ? display_on_pol : !display_on_pol);
}
@@ -217,6 +215,20 @@ void set_lcd_pin(struct platform_device *pdev, int enable)
gpio_direction_output(lcd_standby, 0);
gpio_set_value(lcd_standby, enable ? lcd_standby_pol : !lcd_standby_pol);
}
/********* open backlight just for test ***************/
rk29_mux_api_set(GPIO1B5_PWM0_NAME, 0);
if(0 != gpio_request(RK29_PIN1_PB5, NULL))
{
gpio_free(RK29_PIN1_PB5);
printk(">>>>>> RK29_PIN1_PB5 gpio_request err \n ");
}
gpio_direction_output(RK29_PIN1_PB5, GPIO_HIGH);
gpio_set_value(RK29_PIN1_PB5, GPIO_HIGH);
gpio_direction_output(RK29_PIN1_PB5, GPIO_HIGH);
printk("P1B5 High \n");
/************************/
}
int mcu_do_refresh(struct rk29fb_inf *inf)
@@ -424,6 +436,9 @@ void load_screen(struct fb_info *info, bool initscreen)
u16 x_res = screen->x_res, y_res = screen->y_res;
u32 clk_rate = 0;
u32 dclk_rate = 0;
u32 aclk_rate = 150000000;
if(!g_pdev) return -1;
fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
@@ -487,34 +502,85 @@ void load_screen(struct fb_info *info, bool initscreen)
// let above to take effect
LcdWrReg(inf, REG_CFG_DONE, 0x01);
inf->clk = clk_get(&g_pdev->dev, "hclk_lcdc");
if (!inf->clk || IS_ERR(inf->clk))
{
printk(KERN_ERR "failed to get lcdc_hclk source\n");
return ;
}
inf->dclk = clk_get(&g_pdev->dev, "dclk_lcdc");
if (!inf->dclk || IS_ERR(inf->dclk))
{
printk(KERN_ERR "failed to get lcd dclock source\n");
return ;
}
inf->dclk_divider= clk_get(&g_pdev->dev, "dclk_lcdc_div");
if (!inf->dclk_divider || IS_ERR(inf->dclk_divider))
{
printk(KERN_ERR "failed to get lcd clock lcdc_divider source \n");
return ;
}
if(inf->cur_screen == &inf->lcd_info) {
inf->dclk_parent = clk_get(&g_pdev->dev, "periph_pll");
} else {
inf->dclk_parent = clk_get(&g_pdev->dev, "codec_pll");
}
if (!inf->dclk_parent || IS_ERR(inf->dclk_parent))
{
printk(KERN_ERR "failed to get lcd dclock parent source\n");
return ;
}
inf->aclk = clk_get(&g_pdev->dev, "aclk_lcdc");
if (!inf->aclk || IS_ERR(inf->aclk))
{
printk(KERN_ERR "failed to get lcd clock clk_share_mem source \n");
return ;
}
inf->aclk_parent = clk_get(&g_pdev->dev, "periph_pll");
if (!inf->dclk_parent || IS_ERR(inf->dclk_parent))
{
printk(KERN_ERR "failed to get lcd dclock parent source\n");
return ;
}
// set lcdc clk
if(SCREEN_MCU==screen->type) screen->pixclock = 150; //mcu fix to 150 MHz
clk_set_parent(inf->dclk_divider, inf->dclk_parent);
clk_set_parent(inf->dclk, inf->dclk_divider);
clk_set_parent(inf->aclk, inf->aclk_parent);
dclk_rate = screen->pixclock * 1000000;
fbprintk(">>>>>> set lcdc dclk need %d HZ, clk_parent = %d hz \n ", screen->pixclock, clk_rate);
#if 0
ret = clk_set_rate(inf->dclk_divider, dclk_rate);
if(ret)
{
printk(KERN_ERR ">>>>>> set lcdc dclk_divider faild \n ");
}
if(screen->lcdc_aclk){
aclk_rate = screen->lcdc_aclk * 1000000;
}
ret = clk_set_rate(inf->aclk, aclk_rate);
if(ret){
printk(KERN_ERR ">>>>>> set lcdc dclk_divider faild \n ");
}
clk_enable(inf->dclk);
clk_enable(inf->clk);
clk_enable(inf->clk_share_mem);
#endif
clk_enable(inf->aclk);
// init screen panel
if(screen->init && initscreen)
{
screen->init();
}
}
#ifdef CONFIG_CPU_FREQ
/*
@@ -1246,7 +1312,6 @@ static int win1fb_set_par(struct fb_info *info)
struct fb_fix_screeninfo *fix = &info->fix;
struct rk29fb_screen *screen = inf->cur_screen;
u8 format = 0;
dma_addr_t map_dma;
u32 offset=0, addr=0, map_size=0, smem_len=0;
@@ -1283,10 +1348,9 @@ static int win1fb_set_par(struct fb_info *info)
break;
}
smem_len = fix->line_length * var->yres_virtual + CURSOR_BUF_SIZE; //cursor buf also alloc here
smem_len = fix->line_length * var->yres_virtual; //cursor buf also alloc here
map_size = PAGE_ALIGN(smem_len);
if (smem_len != fix->smem_len) // buffer need realloc
{
fbprintk(">>>>>> win1 buffer size is change(%d->%d)! remap memory!\n",fix->smem_len, smem_len);
@@ -1316,7 +1380,6 @@ static int win1fb_set_par(struct fb_info *info)
addr = fix->smem_start + offset;
LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE|m_W1_FORMAT, v_W1_ENABLE(1)|v_W1_FORMAT(format));
xpos += (screen->left_margin + screen->hsync_len);
@@ -1708,18 +1771,6 @@ static int __init rk29fb_probe (struct platform_device *pdev)
}
inf->preg = (LCDC_REG*)inf->reg_vir_base;
if(0)
{
struct resource *rtc_mem = NULL;
u32 rtc_reg_vir_base = NULL;
rtc_mem = request_mem_region(RK29_RTC_PHYS, RK29_RTC_SIZE, NULL);
rtc_reg_vir_base = (u32)ioremap(RK29_RTC_PHYS, RK29_RTC_SIZE);
u32 rtc_reg = __raw_readl(rtc_reg_vir_base+0x04);
__raw_writel( rtc_reg | 0x02, rtc_reg_vir_base+0x04 );
rtc_reg = __raw_readl(rtc_reg_vir_base+0x04);
}
/* Prepare win1 info */
fbprintk(">> Prepare win1 info \n");
inf->win1fb = framebuffer_alloc(sizeof(struct win1_par), &pdev->dev);
@@ -1837,50 +1888,12 @@ static int __init rk29fb_probe (struct platform_device *pdev)
/* because after register_framebuffer, the win1fb_check_par and winfb_set_par execute immediately */
fbprintk(">> Init all lcdc and lcd before register_framebuffer \n");
init_lcdc(inf->win1fb);
#if 0
inf->clk = clk_get(&pdev->dev, "lcdc_hclk");
if (!inf->clk || IS_ERR(inf->clk))
{
printk(KERN_ERR "failed to get lcdc_hclk source\n");
ret = -ENOENT;
goto unregister_win1fb;
}
inf->dclk = clk_get(&pdev->dev, "lcdc");
if (!inf->dclk || IS_ERR(inf->dclk))
{
printk(KERN_ERR "failed to get lcd dclock source\n");
ret = -ENOENT;
goto unregister_win1fb;
}
inf->dclk_parent = clk_get(&pdev->dev, "arm_pll");
if (!inf->dclk_parent || IS_ERR(inf->dclk_parent))
{
printk(KERN_ERR "failed to get lcd dclock parent source\n");
ret = -ENOENT;
goto unregister_win1fb;
}
inf->dclk_divider= clk_get(&pdev->dev, "lcdc_divider");
if (!inf->dclk_divider || IS_ERR(inf->dclk_divider))
{
printk(KERN_ERR "failed to get lcd clock lcdc_divider source \n");
ret = -ENOENT;
goto unregister_win1fb;
}
inf->clk_share_mem = clk_get(&pdev->dev, "lcdc_share_memory");
if (!inf->clk_share_mem || IS_ERR(inf->clk_share_mem))
{
dev_err(&pdev->dev, "failed to get lcd clock clk_share_mem source \n");
ret = -ENOENT;
goto unregister_win1fb;
}
#ifdef CONFIG_CPU_FREQ
inf->freq_transition.notifier_call = rk29fb_freq_transition;
cpufreq_register_notifier(&inf->freq_transition, CPUFREQ_TRANSITION_NOTIFIER);
// inf->freq_transition.notifier_call = rk29fb_freq_transition;
// cpufreq_register_notifier(&inf->freq_transition, CPUFREQ_TRANSITION_NOTIFIER);
#endif
fbprintk("got clock\n");
#endif
if(mach_info)
{
@@ -1908,7 +1921,7 @@ static int __init rk29fb_probe (struct platform_device *pdev)
mach_info->io_init(&fb_setting);
}
//set_lcd_pin(pdev, 1);
set_lcd_pin(pdev, 1);
mdelay(10);
g_pdev = pdev;
inf->mcu_usetimer = 1;