资讯详情

rk3288 开机动态切换lvds屏幕显示(二)uboot修改设备树

上一篇lcdservice中间,会带lvds_parameter=8_800_写入480类似的屏幕标志misc分区指定位置,重启系统后uboot会从misc分区中读出lvds_parameter=8_800_480标志,然后在设备树中找到与标志对应的标志lvds屏幕配置节点,并配置相应的节点。

1、uboot读取misc分区指定数据

u-boot/drivers/video/rockchip_display.c

#if 1 extern const disk_partition_t* get_disk_partition(const char *name); extern int StorageReadLba(uint32 LBA, void *pbuf, uint32 nSec);  #define CUSTOM_PARTITION_NAME "misc" #define LCD_PARAM_MAX_COUNT 25  int lcdParam[LCD_PARAM_MAX_COUNT]; char param_buf_temp[100] = {0};  int get_lcdparam_info_from_custom_partition() {  const disk_partition_t *ptn1 = get_disk_partition(CUSTOM_PARTITION_NAME);  int i;   if (!ptn1) {   printf("OEM partition not found!\n");   return -1;  }   printf("block num: %lu, name %s ,type %s,block size :%lu\n",ptn1->size,ptn1->name,ptn1->type,ptn1->blksz);   if (StorageReadLba(ptn1->start 2, param_buf_temp, DIV_ROUND_UP(sizeof(param_buf_temp), RK_BLK_SIZE)) != 0) {   printf("failed to read oem!= 0) {   printf("failed to read oem!\n");   return -1;  }  printf("%s \n",param_buf_temp);   return 0; }  #endif

需要注意ptn1->start指针一次偏移512个字节。

2.验证屏幕标志,获取设备树屏节点

u-boot/drivers/video/rockchip_display.c

static char *get_screen_para(void *blob, int parent_node, char *screen_buf,int len) {  if((screen_buf == NULL) || (len <= 0) || (parent_node <= 0))   return NULL;   memset(screen_buf,'\0',len);  if(strstr(param_buf_temp, "7_800_480_18") || strstr(param_buf_temp, "7_800_480_24")) {   strcpy(screen_buf,"inch8rgb");  } else if(strstr(param_buf_temp, "10_4_1024_768")) {   strcpy(screen_buf,"g104x1-l04");  } else if(strstr(param_buf_temp, "15_1024_768")) {   strcpy(screen_buf,"ldb15xga");  } else if(strstr(param_buf_temp, "17_1280_1024")) {   strcpy(screen_buf,"M170ETN01");  } else if(strstr(param_buf_temp, "19_1440_900")) {   strcpy(screen_buf,"M190PW01");  } else if(strstr(param_buf_temp, "21_5_1920_1080")) {   strcpy(screen_buf,"t215hvn01");  } else if(strstr(param_buf_temp, "32_1920_1080")) {   strcpy(screen_buf,"LD320DUE");  } else if(strstr(param_buf_temp, "10_1_1280_800")) {   strcpy(screen_buf,"g101ice");  } else {   printf("no find screen\n");   return NULL;  }   int i = 0,ret = 0;  char *output = NULL;  for (i=parent_node;i>=0;i  )  {   output = (char *)fdt_getprop_by_offset(blob, i, NULL, &ret);   if (output != NULL) {    if((strncmp(output, "duallvds", 8)==0) || (strncmp(output, "lvds", 4)==0)) {     printf("****output: %s -- offset : %d\n",output,i);     break;    }   }  }  return screen_buf; }

3.在设备树中找到屏幕配置节点,并修改为新设置节点

u-boot/drivers/video/rockchip_display.c

static int fdt_fixup_display_sub_route(void *blob, const char *name,            enum fdt_status status) {  int route, phandle, connect, connector, panel, dt, timing;  char path[64];  int ret;  int offset = 0;  int len;  char *screen_node = NULL;  char screen_buf[20] = {0};  char *screen_name = NULL;   sprintf(path, "/display-subsystem/route/route-%s", name);   route = fdt_path_offset(blob, path);  if (route < 0)   return route;  /* fixup route status */  ret = fdt_fixup_node_status(blob, route, status);  if (ret < 0)   return ret;  phandle = fdt_getprop_u32_default_node(blob, route, 0, "connect", -1);  if (phandle < 0)   return phandle;  connect = fdt_node_offset_by_phandle(blob, phandle);  if (connect < 0)   return connect;  connector = find_connector_node(blob, connect);  if (connector < 0)   return connector;  /* fixup connector status */  ret = fdt_fixup_node_status(blob, connector, status);  if (ret < 0)   return ret;  if (status != FDT_STATUS_OKAY)   return 0;  panel = get_panel_node(blob, connector);  if (panel < 0)   return panel;   dt = fdt_subnode_offset(blob, panel, "display-timings");  if (dt < 0)   return dt;  timing = fdt_subnode_offset(blob, dt, "timing");  if (timing < 0) {   phandle = fdt_getprop_u32_default_node(blob, dt, 0, "native-mode", -1);   if (phandle < 0)    return phandle;    timing = fdt_node_offset_by_phandle_node(blob, dt, phandle);   if (timing < 0)    return timing;  }   screen_name = get_screen_para(blob,panel,screen_buf,sizeof(screen_buf));  if(screen_name == NULL) {   return -1;  } else{   ret = fdt_set_phandle(blob,timing,0);  }  for(offset = dt;(offset >=0);(offset = fdt_next_node(blob, offset,&len))) {   screen_node = fdt_get_name(blob,offset,&len);   printf("name = %s -- offset = %d\n",screen_node,offset);   if (screen_node != NULL) {    if(strncmp(screen_buf,screen_node,strlen(screen_node)) == 0) {     printf("offset = %d -- name = %s\n", offset, fdt_get_name(blob,offset,&len));     break;    }   }  }  fdt_set_phandl(blob,offset,phandle);
	uint32_t screen_7_18 = 18;
	uint32_t screen_7_24 = 24;
	if(strstr(param_buf_temp, "7_800_480_18")) {
		fdt_setprop_u32(blob,panel,"rockchip,data-width",screen_7_18);
	} else {
		fdt_setprop_u32(blob,panel,"rockchip,data-width",screen_7_24);
	}

	if((strcmp(screen_buf,"inch8rgb")==0) || (strcmp(screen_buf,"g104x1-l04")==0) || (strcmp(screen_buf,"g101ice")==0) || (strcmp(screen_buf,"ldb15xga")==0)) {
		fdt_setprop_string(blob,panel,"rockchip,output","lvds");
	} else if ((strcmp(screen_buf,"M170ETN01")==0) || (strcmp(screen_buf,"M190PW01")==0) || (strcmp(screen_buf,"t215hvn01")==0) || (strcmp(screen_buf,"LD320DUE")==0)) {
		fdt_setprop_string(blob,panel,"rockchip,output","duallvds");
	}

	int i = 0;
	char *output = NULL;
	for (i=panel;i>=0;i++)
	{
		output = (char *)fdt_getprop_by_offset(blob, i, NULL, &ret);
		if (output != NULL) {
			if((strncmp(output, "duallvds", 8)==0) || (strncmp(output, "lvds", 4)==0)) {
				printf("output: %s -- offset : %d\n",output,i);
				break;
			}
		}
	}

	return 0;
}

设备树修改完成后,uboot正常引导内核启动,内核加载新的设备树,启动后会按照新的屏幕显示。

注意事项:lvds屏幕默认电压不一致,有时可能会出现电压过高烧屏问题,建议在修改屏幕参数时接hdmi屏幕或使用adb投屏方式

adb投屏软件:

链接:https://pan.baidu.com/s/1fYxbAhyBsM-ugB6WqiIeww  提取码:xite

标签: g101cb光电传感器g101p光纤传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司