您的位置:首页 > 移动开发 > Android开发

android uboot 环境变量配置fb及双屏显示(vga、lcd)

2017-06-07 09:31 507 查看
上周公司终于拿到了freescale i.MX53的QSB板,经过一些折腾之后终于在上面把android跑起来了,按照所给的user guide测试了一下VGA、HDMI等,一切正常,但是都是单独显示的,和公司要开发的车载产品有很大距离,公司要开发的产品的大概要求是:

1、支持前后台显示(前台lcd显示由司机操作、后台TV输出供乘客观看电影及地图导航显示)

2、7.1声道,同时解码两路audio并能让两路声音分离

……………………

把相关的文档看了几遍,上面有介绍双屏显示的,但都是针对i.MX51的,53是刚出来不久的芯片,A8核心+硬解码器

通过参考51的双屏显示设置及uboot环境配置,终于在53的QSB板上作到了双屏显示(后台通过VGA输出、QSB板上的HDMI是接到了FB0上,占用了lcd的FB,所以还没用HDMI作为后台输出)

基本的过程如下:

1、把板子连接上串口和VGA,用电脑显示器作为输出

2、重启系统后在串口中出现如下提示的时候按回车进入uboot环境配置状态
U-Boot 2009.08-00246-gf56947c-dirty ( 6月 06 2011 - 23:02:35)

CPU:   Freescale i.MX53 family 2.0V at 1000 MHz
mx53 pll1: 1000MHz
mx53 pll2: 400MHz
mx53 pll3: 216MHz
mx53 pll4: 455MHz
ipg clock     : 66666666Hz
ipg per clock : 33333333Hz
uart clock    : 21600000Hz
cspi clock    : 54000000Hz
ahb clock     : 133333333Hz
axi_a clock   : 400000000Hz
axi_b clock   : 200000000Hz
emi_slow clock: 133333333Hz
ddr clock     : 400000000Hz
esdhc1 clock  : 80000000Hz
esdhc2 clock  : 80000000Hz
esdhc3 clock  : 80000000Hz
esdhc4 clock  : 80000000Hz
nfc clock     : 26666666Hz
Board: MX53-LOCO 1.0
Boot Reason: [WDOG]
Boot Device: SD
I
4000
2C:   ready
DRAM:   1 GB
MMC:   FSL_ESDHC: 0, FSL_ESDHC: 1
In:    serial
Out:   serial
Err:   serial
Checking for recovery command file...
Net:   got MAC address from IIM: 00:04:9f:01:a9:8a
FEC0 [PRIME]
Hit any key to stop autoboot:  0
MX53-LOCO U-Boot >


输入
MX53-LOCO U-Boot > printenv


可看到一些默认的环境设置如下:
bootdelay=3
baudrate=115200
loadaddr=0x70800000
netdev=eth0
ethprime=FEC0
bootdelay=3
uboot=u-boot.bin
kernel=uImage
loadaddr=0x70800000
rd_loadaddr=0x70C00000
nfsroot=/opt/eldk/arm
bootargs_base=setenv bootargs console=ttymxc0,115200
vga=setenv bootargs ${bootargs} init=/init androidboot.console=ttymxc0 di1_primary tve
lcd=setenv bootargs ${bootargs} init=/init androidboot.console=ttymxc0 di0_primary calibration
hdmi=setenv bootargs ${bootargs} init=/init androidboot.console=ttymxc0 video=mxcdi0fb:RGB24,1080P60 tve gpu_memory=256M
claa_lcd=setenv bootargs ${bootargs} init=/init androidboot.console=ttymxc0 video=mxcdi0fb:RGB565,CLAA-WVGA calibration
bootcmd_SD1=run bootargs_base bootargs_android
bootcmd_SD2=mmc read 0 ${loadaddr} 0x800 0x1800;mmc read 0 ${rd_loadaddr} 0x3000 0x300;bootm ${loadaddr} ${rd_loadaddr}
bootargs_nfs=setenv bootargs ${bootargs} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
bootcmd_net=run bootargs_base bootargs_nfs; tftpboot ${loadaddr} ${kernel}; bootm
bootcmd_android_recovery=run bootargs_base bootargs_android_recovery;mmc read 0 ${loadaddr} 0x800 0x1800;bootm
bootargs_android_recovery=setenv bootargs ${bootargs} init=/init root=/dev/mmcblk0p4 rootfs=ext4
ethact=FEC0


其中
vga=setenv bootargs ${bootargs} init=/init androidboot.console=ttymxc0 di1_primary tve
lcd=setenv bootargs ${bootargs} init=/init androidboot.console=ttymxc0 di0_primary calibration
hdmi=setenv bootargs ${bootargs} init=/init androidboot.console=ttymxc0 video=mxcdi0fb:RGB24,1080P60 tve gpu_memory=256M


代表的是分别用vga、lcd、hdmi作为输出的一些配置

要想做到双屏显示就得重新配置一下uboot的环境,我现在的配置参数如下:
setenv bootargs_android 'setenv bootargs ${bootargs} init=/init androidboot.console=ttymxc0 di0_primary calibration video=mxcdi1fb:RGB565,720P60 tve'


几点说明:

1、init=/init表示的是android启动的init.rc文件的位置

2、androidboot.console=ttymxc0表示的是系统debug时所使用的串口为tty0

3、di0_primary 表示的是把lcd挂到fb0上作为主显示,而calibration则是触摸屏

4、video=mxcdi1fb:RGB565,720P60 tve 表示的是把video输出挂到fb1上,输出的数据格式为RGB565,720P60

设置好上面这些环境变量之后,然后输入
MX53-LOCO U-Boot > saveenv
Saving Environment to MMC...
Writing to MMC(0)... done
MX53-LOCO U-Boot > boot


系统将会重新启动

等系统启动完成后在串中输入
#echo U:1280x1024p-60 > /sys/class/graphics/fb1/mode
#echo 1 >/sys/class/graphics/fb1/blank
#echo 0 >/sys/class/graphics/fb1/blank
#setprop rw.SECOND_DISPLAY_CONNECTED 1
#setprop sys.SECOND_DISPLAY_ENABLED 1


关于上面设置参数的几点说明:

1、echo U:1280x1024p-60 > /sys/class/graphics/fb1/mode 是设置TV输出的显示模式,在uboot的源码

Videomodes.c文件中有如下19种输出模式
const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT] = {
{0x301, RES_MODE_640x480, 8},
{0x310, RES_MODE_640x480, 15},
{0x311, RES_MODE_640x480, 16},
{0x312, RES_MODE_640x480, 24},
{0x303, RES_MODE_800x600, 8},
{0x313, RES_MODE_800x600, 15
18769
},
{0x314, RES_MODE_800x600, 16},
{0x315, RES_MODE_800x600, 24},
{0x305, RES_MODE_1024x768, 8},
{0x316, RES_MODE_1024x768, 15},
{0x317, RES_MODE_1024x768, 16},
{0x318, RES_MODE_1024x768, 24},
{0x161, RES_MODE_1152x864, 8},
{0x162, RES_MODE_1152x864, 15},
{0x163, RES_MODE_1152x864, 16},
{0x307, RES_MODE_1280x1024, 8},
{0x319, RES_MODE_1280x1024, 15},
{0x31A, RES_MODE_1280x1024, 16},
{0x31B, RES_MODE_1280x1024, 24},
};


但是代码里真正实现的只有如下12种

RES_MODE_640x480 bpp8

RES_MODE_640x480 bpp16

RES_MODE_640x480 bpp24

RES_MODE_800x600 bpp8

RES_MODE_800x600 bpp16

RES_MODE_800x600 bpp24

RES_MODE_1024x768 bpp8

RES_MODE_1024x768 bpp16

RES_MODE_1024x768 bpp24

RES_MODE_1280x1024 bpp8

RES_MODE_1280x1024 bpp16

RES_MODE_1280x1024 bpp24

具体实现的代码在Ati_radeon_fb.c文件中

代码如下:


void
radeon_setmode_9200(int vesa_idx, int bpp)
void radeon_setmode_9200(int vesa_idx, int bpp)
{
struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));

mode->crtc_gen_cntl = CRTC_EN | CRTC_EXT_DISP_EN;
mode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | CRTC_CRT_ON;
mode->dac_cntl = DAC_MASK_ALL | DAC_VGA_ADR_EN | DAC_8BIT_EN;
mode->crtc_offset_cntl = CRTC_OFFSET_CNTL__CRTC_TILE_EN;

switch (bpp) {
case 24:
mode->crtc_gen_cntl |= 0x6 << 8; /* x888 */
#if defined(__BIG_ENDIAN)
mode->surface_cntl = NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP;
mode->surf_info[0] = NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP;
#endif
break;
case 16:
mode->crtc_gen_cntl |= 0x4 << 8; /* 565 */
#if defined(__BIG_ENDIAN)
mode->surface_cntl = NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP;
mode->surf_info[0] = NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP;
#endif
break;
default:
mode->crtc_gen_cntl |= 0x2 << 8; /* palette */
mode->surface_cntl = 0x00000000;
break;
}

switch (vesa_idx) {
case RES_MODE_1280x1024:
mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1688,1280);
mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(1066,1024);
mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(1025,3);
#if defined(CONFIG_RADEON_VREFRESH_75HZ)
mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1288,18);
mode->ppll_p_3 = 0x00010078;
#else /* default @ 60 Hz */
mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1320,14);
mode->ppll_p_3 = 0x00010060;
#endif
/*
* for this mode pitch expands to the same value for 32, 16 and 8 bpp,
* so we set it here once only.
*/
mode->crtc_pitch = RADEON_CRT_PITCH(1280,32);
switch (bpp) {
case 24:
mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1280 * 4 / 16);
mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,32);
break;
case 16:
mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1280 * 2 / 16);
mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,16);
break;
default: /* 8 bpp */
mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1280 * 1 / 16);
mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,8);
break;
}
break;
case RES_MODE_1024x768:
#if defined(CONFIG_RADEON_VREFRESH_75HZ)
mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1312,1024);
mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1032,12);
mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(800,768);
mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(769,3);
mode->ppll_p_3 = 0x0002008c;
#else /* @ 60 Hz */
mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1344,1024);
mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1040,17) | CRTC_H_SYNC_POL;
mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(806,768);
mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(771,6) | CRTC_V_SYNC_POL;
mode->ppll_p_3 = 0x00020074;
#endif
/* also same pitch value for 32, 16 and 8 bpp */
mode->crtc_pitch = RADEON_CRT_PITCH(1024,32);
switch (bpp) {
case 24:
mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1024 * 4 / 16);
mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,32);
break;
case 16:
mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1024 * 2 / 16);
mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,16);
break;
default: /* 8 bpp */
mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1024 * 1 / 16);
mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,8);
break;
}
break;
case RES_MODE_800x600:
mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1056,800);
#if defined(CONFIG_RADEON_VREFRESH_75HZ)
mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(808,10);
mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(625,600);
mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(601,3);
mode->ppll_p_3 = 0x000300b0;
#else /* @ 60 Hz */
mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(832,16);
mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(628,600);
mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(601,4);
mode->ppll_p_3 = 0x0003008e;
#endif
switch (bpp) {
case 24:
mode->crtc_pitch = RADEON_CRT_PITCH(832,32);
mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (832 * 4 / 16);
mode->surf_upper_bound[0] = SURF_UPPER_BOUND(832,600,32);
break;
case 16:
mode->crtc_pitch = RADEON_CRT_PITCH(896,16);
mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (896 * 2 / 16);
mode->surf_upper_bound[0] = SURF_UPPER_BOUND(896,600,16);
break;
default: /* 8 bpp */
mode->crtc_pitch = RADEON_CRT_PITCH(1024,8);
mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1024 * 1 / 16);
mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,600,8);
break;
}
break;
default: /* RES_MODE_640x480 */
#if defined(CONFIG_RADEON_VREFRESH_75HZ)
mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(840,640);
mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(648,8) | CRTC_H_SYNC_POL;
mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(500,480);
mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(481,3) | CRTC_V_SYNC_POL;
mode->ppll_p_3 = 0x00030070;
#else /* @ 60 Hz */
mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(800,640);
mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(674,12) | CRTC_H_SYNC_POL;
mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(525,480);
mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(491,2) | CRTC_V_SYNC_POL;
mode->ppll_p_3 = 0x00030059;
#endif
/* also same pitch value for 32, 16 and 8 bpp */
mode->crtc_pitch = RADEON_CRT_PITCH(640,32);
switch (bpp) {
case 24:
mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (640 * 4 / 16);
mode->surf_upper_bound[0] = SURF_UPPER_BOUND(640,480,32);
break;
case 16:
mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (640 * 2 / 16);
mode->surf_upper_bound[0] = SURF_UPPER_BOUND(640,480,16);
break;
default: /* 8 bpp */
mode->crtc_offset_cntl = 0x00000000;
break;
}
break;
}

OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl | CRTC_DISP_REQ_EN_B);
OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
OUTREG(CRTC_OFFSET, 0);
OUTREG(CRTC_OFFSET_CNTL, mode->crtc_offset_cntl);
OUTREG(CRTC_PITCH, mode->crtc_pitch);
OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);

mode->clk_cntl_index = 0x300;
mode->ppll_ref_p = 0xc;

radeon_write_pll_regs(rinfo, mode);

OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
OUTREG(SURFACE0_INFO, mode->surf_info[0]);
OUTREG(SURFACE0_LOWER_BOUND, 0);
OUTREG(SURFACE0_UPPER_BOUND, mode->surf_upper_bound[0]);
OUTREG(SURFACE_CNTL, mode->surface_cntl);

if (bpp > 8)
set_pal();

free(mode);
}


2、echo 1 >/sys/class/graphics/fb1/blank 是关闭fb1

而echo 0 >/sys/class/graphics/fb1/blank 则是打开fb1

3、setprop rw.SECOND_DISPLAY_CONNECTED 1 我理解的是允许TV输出连接至fb

而setprop sys.SECOND_DISPLAY_ENABLED 1则是开启fb的数据输出  

(不知道是否有哪位对这些参数有更具体的了解和说明)

设置为上面这些之后,把显示器的VGA线接到板子的VGA上就可以看到在显示器显示的内容是和lcd的显示同步的

目前有几个疑点,希望看到的同行指点:

1、如何做到只让显示器输出的图像是板子上播放的视频内容,而UI部分不会显示

2、我找了个可以支持后台播放的视频播放器,开始播放视频后,我设置播放器“play in background”让其在后台播放,这时就会退出到UI显示状态,而工具栏上显示播放已经在后台播放视频了,lcd上显示正常,而显示器上则显示为:黑色的底图已经变成了当前正在后台播放的视频,运用程序的小图标则浮在了视频上面

3、在网上下了个RockPlay播放器,打开视频的时候会提示用哪种解码方式,我先选择了硬解码方式,这时播放的视频内容可以在显示器上正常显示,而lcd上则为黑色的,只有播放器的UI可以显示;然后我又选择了软解码方式,这时播放的视频内容在显示器上和lcd上都可以显示!!!由于视频的片源为720P的,软解码的效果比硬解码要差很多,而且软解码为会做到自动适应显示器的宽度!!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: