天天看點

rk3288 設定imx6ull的lcd控制器的寄存器使用參數設定LCD控制器

使用參數設定LCD控制器

根據晶片手冊,一個一個設定寄存器:

  • Framebuffer位址設定(基位址)
  • Framebuffer中資料格式設定
  • LCD時序參數設定
  • LCD引腳極性設定

主要是根據imx6ull的晶片手冊一個一個設定相關的寄存器,也沒有什麼取巧的辦法。

static void lcd_controller_enable(struct imx6ull_lcdif *lcdif)
{
	lcdif->CTRL |= (1<<0);
}

static int lcd_controller_init(struct imx6ull_lcdif *lcdif, 
		struct display_timing *dt, int lcd_bpp, int fb_bpp, 
		unsigned int fb_phy)
{
	int lcd_data_bus_width;
	int fb_width;
	int vsync_pol = 0;
	int hsync_pol = 0;
	int dotclk_pol = 0;
	int de_pol = 0;

	switch(lcd_bpp) {
	case 16:
		lcd_data_bus_width = 0x0;
		break;
	case 8:
		lcd_data_bus_width = 0x1;
		break;
	case 18:
		lcd_data_bus_width = 0x2;
		break;
	case 24:
		lcd_data_bus_width = 0x3;
		break;
	default:
		lcd_data_bus_width = 0x0;
		break;
	}

	switch(fb_bpp) {
	case 16:
		fb_width = 0x0;
		break;
	case 8:
		fb_width = 0x1;
		break;
	case 18:
		fb_width = 0x2;
		break;
	case 24:
	case 32:
		fb_width = 0x3;
		break;
	default:
		fb_width = 0x0;
		break;
	}
	/* 
     * 初始化LCD控制器的CTRL寄存器
     * [19]       :  1      : DOTCLK和DVI modes需要設定為1 
     * [17]       :  1      : 設定為1工作在DOTCLK模式
     * [15:14]    : 00      : 輸入資料不交換(小端模式)預設就為0,不需設定
     * [13:12]    : 00      : CSC資料不交換(小端模式)預設就為0,不需設定
     * [11:10]    : 11		: 資料總線為24bit
     * [9:8]    根據顯示屏資源檔案bpp來設定:8位0x1 , 16位0x0 ,24位0x3
     * [5]        :  1      : 設定elcdif工作在主機模式
     * [1]        :  0      : 24位資料均是有效資料,預設就為0,不需設定
	 */	
	lcdif->CTRL = (0<<30) | (0<<29) | (0<<28) | (1<<19) | (1<<17) | (lcd_data_bus_width << 10) |\
			  (fb_width << 8) | (1<<5);

	/*
	* 設定ELCDIF的寄存器CTRL1
	* 根據bpp設定,bpp為24或32才設定
	* [19:16]  : 111  :表示ARGB傳輸格式模式下,傳輸24位無壓縮資料,A通道不用傳輸)
	*/	
	if(fb_bpp == 24 || fb_bpp == 32) {
		lcdif->CTRL1 &= ~(0xf << 16);
		lcdif->CTRL1 |= (0x7 << 16);
	} else {
		lcdif->CTRL1 |= (0xf << 16);
	}

	/*
	* 設定ELCDIF的寄存器TRANSFER_COUNT寄存器
	* [31:16]  : 垂直方向上的像素個數  
	* [15:0]   : 水準方向上的像素個數
	*/
	lcdif->TRANSFER_COUNT = (dt->vactive.typ << 16 )| (dt->hactive.typ<<0);


	if(dt->flags & DISPLAY_FLAGS_HSYNC_HIGH)
		hsync_pol = 1;
	if(dt->flags & DISPLAY_FLAGS_VSYNC_HIGH)
		vsync_pol = 1;
	if(dt->flags & DISPLAY_FLAGS_DE_HIGH)
		de_pol = 1;
	if(dt->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
		dotclk_pol = 1;

	/*
	* 設定ELCDIF的VDCTRL0寄存器
	* [29] 0 : VSYNC輸出  ,預設為0,無需設定
	* [28] 1 : 在DOTCLK模式下,設定1硬體會産生使能ENABLE輸出
	* [27] 0 : VSYNC低電平有效	,根據螢幕配置檔案将其設定為0
	* [26] 0 : HSYNC低電平有效 , 根據螢幕配置檔案将其設定為0
	* [25] 1 : DOTCLK下降沿有效 ,根據螢幕配置檔案将其設定為1
	* [24] 1 : ENABLE信号高電平有效,根據螢幕配置檔案将其設定為1
	* [21] 1 : 幀同步周期機關,DOTCLK mode設定為1
	* [20] 1 : 幀同步脈沖寬度機關,DOTCLK mode設定為1
	* [17:0] :  vysnc脈沖寬度 
	*/
	lcdif->VDCTRL0 = (1 << 28) | (vsync_pol << 27) | (hsync_pol << 26) | (dotclk_pol << 25) | (de_pol << 24) | (1<<21) |
		(1<<20) | (dt->vsync_len.typ << 0);

	/*
	* 設定ELCDIF的VDCTRL1寄存器
	* 設定垂直方向的總周期:上黑框tvb+垂直同步脈沖tvp+垂直有效高度yres+下黑框tvf
	*/	  
	lcdif->VDCTRL1 = dt->vback_porch.typ + dt->vsync_len.typ + dt->vactive.typ + dt->vfront_porch.typ;

	/*
	* 設定ELCDIF的VDCTRL2寄存器
	* [18:31]  : 水準同步信号脈沖寬度
	* [17: 0]   : 水準方向總周期
	* 設定水準方向的總周期:左黑框thb+水準同步脈沖thp+水準有效高度xres+右黑框thf
	*/
	lcdif->VDCTRL2 = (dt->hsync_len.typ << 18)| (dt->hback_porch.typ + dt->hsync_len.typ + dt->hactive.typ + dt->hfront_porch.typ) << 0;

	/*
	* 設定ELCDIF的VDCTRL3寄存器
	* [27:16] :水準方向上的等待時鐘數 =thb + thp
	* [15:0]  : 垂直方向上的等待時鐘數 = tvb + tvp
	*/ 
	lcdif->VDCTRL3 = (dt->hback_porch.typ + dt->hsync_len.typ) << 16 |
		((dt->vback_porch.typ + dt->vsync_len.typ) << 0);

	/*
	* 設定ELCDIF的VDCTRL4寄存器
	* [18]	   使用VSHYNC、HSYNC、DOTCLK模式此為置1
	* [17:0]  : 水準方向的寬度
	*/ 
	lcdif->VDCTRL4 = (1 << 18) | (dt->hactive.typ);

	/*
	* 設定ELCDIF的CUR_BUF和NEXT_BUF寄存器
	* CUR_BUF	 :	目前顯存位址
	* NEXT_BUF :	下一幀顯存位址
	* 友善運算,都設定為同一個顯存位址
	*/
	lcdif->CUR_BUF = fb_phy;
	lcdif->NEXT_BUF = fb_phy;

	return 0;
}
           

使能LCD函數

static void lcd_controller_enable(struct imx6ull_lcdif *lcdif)
{
	lcdif->CTRL |= (1<<0);
}
           

在probe函數調用函數

probe:
{
	//...
	lcd_controller_init(lcdif, dt, bits_per_pixel, 16,  phy_addr);

	lcd_controller_enable(lcdif);
	//...
}
           

繼續閱讀